C# 等待所有异步web服务调用返回
我有一个桌面应用程序(.net 3.5),它使用经典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
我需要对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;}?