Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 等待所有异步web服务调用返回_C#_Multithreading_Synchronization - Fatal编程技术网

C# 等待所有异步web服务调用返回

C# 等待所有异步web服务调用返回,c#,multithreading,synchronization,C#,Multithreading,Synchronization,我有一个桌面应用程序(.net 3.5),它使用经典web服务与服务器通信。 我需要对web服务函数进行多次调用,等待它们全部完成,然后继续 我想同时打这些电话;因此,显然我希望利用myfunctionsync方法。 问题是-我不知道如何验证所有呼叫是否已返回。我可能缺少一些简单的同步机制 以下是我希望能够做到的: public void DoWork() { service.MyFuncCompleted+= MyFunc_Completed; foreach (var i in

我有一个桌面应用程序(.net 3.5),它使用经典web服务与服务器通信。
我需要对web服务函数进行多次调用,等待它们全部完成,然后继续

我想同时打这些电话;因此,显然我希望利用
myfunctionsync
方法。
问题是-我不知道如何验证所有呼叫是否已返回。我可能缺少一些简单的同步机制

以下是我希望能够做到的:

public void DoWork()
{
   service.MyFuncCompleted+= MyFunc_Completed;
   foreach (var i in items)
   {
      service.MyFuncAsync(i);
      syncMechanism.WaitForAnother(1);  //signal that we have to wait for 1 more task to finish
   }
   syncMechanism.WaitForAllTasksToFinsih();  //wait until specified number of tasks have finished

   //continue
}

public void MyFunc_Completed(EventArgs e)
{
   //process result...
   syncMechanism.Signal(1);  //signal that 1 task has finished
}
任何人都知道这是c#?

这(fork/join)在.NET4中要容易得多,但是你现在使用的是3.5,所以你必须用老式的方式来做


基本上,为每个操作增加一个计数器,然后在
Completed
处理程序中减少它。然后检查它是否降到零,如果降到零,则发送一个等待句柄以指示所有操作都已完成

下面是一个例子:

static ManualResetEvent mre = new ManualResetEvent( false );
static int inFlight = 1; // start with 1 to fix race condition

static void DoWork()
{
    for ( int i = 0 ; i < 10 ; i++ )
    {
        var bw = new BackgroundWorker();

        bw.DoWork += bw_DoWork;
        bw.RunWorkerCompleted += bw_RunWorkerCompleted;

        Interlocked.Increment( ref inFlight );

        bw.RunWorkerAsync();
    }

    if ( Interlocked.Decrement( ref inFlight ) == 0 ) mre.Set();

    mre.WaitOne(); // this blocks until all workers have completed
}

static void bw_DoWork( object sender, DoWorkEventArgs e )
{
    Thread.Sleep( 1000 );
}

static void bw_RunWorkerCompleted( object sender, RunWorkerCompletedEventArgs e )
{
    if ( Interlocked.Decrement( ref inFlight ) == 0 ) mre.Set();
}
static ManualResetEvent mre=新的ManualResetEvent(假);
飞行中的静态int=1;//从1开始修复竞争条件
静态空心榫钉()
{
对于(int i=0;i<10;i++)
{
var bw=新的BackgroundWorker();
bw.DoWork+=bw_DoWork;
bw.RunWorkerCompleted+=bw_RunWorkerCompleted;
联锁。增量(飞行中参考);
RunWorkerAsync();
}
如果(联锁减量(参考飞行中)==0)mre.Set();
mre.WaitOne();//此操作将一直阻止,直到所有工作人员都完成为止
}
静态void bw_DoWork(对象发送方,DoWorkEventArgs e)
{
睡眠(1000);
}
静态void bw_RunWorkerCompleted(对象发送方,RunWorkerCompletedEventArgs e)
{
如果(联锁减量(参考飞行中)==0)mre.Set();
}

我不使用简单的计数器,而是使用hashmap,其中键是线程id(或webservice名称,或任何您可以轻松处理的名称)

使用字符串或对象(表示调用时间)作为值

当给定调用返回时,从hashmap中删除相应的项

当hashmap为空时,您知道可以继续。 如果在很长一段时间后它不是空的(这基本上是您所做的调用集合的超时),您可以在hashmap中检查哪一个仍然挂起,以及需要多长时间


或者,您可以使用更复杂的对象作为值,并将失败者的返回代码与原始时间戳一起记录(在这种情况下,您拥有的信息比“返回的信息”更完整)。

“检查是否已降到零”:您建议如何做?忙着等吗<代码>(while(true){if(counter==0)break;}?