C# 如何并行执行多个异步调用?
我有许多命令可以调用soapweb服务(betfairapi)。都是经典的异步编程模型类型C# 如何并行执行多个异步调用?,c#,asynchronous,C#,Asynchronous,我有许多命令可以调用soapweb服务(betfairapi)。都是经典的异步编程模型类型 public void DoXXX( <input parameters ...> ) { XXXRequest Request = new XXXRequest(); // populate Request from input parameters ... BetfairService.BeginXXX( Request, XXXCallback, State );
public void DoXXX( <input parameters ...> )
{
XXXRequest Request = new XXXRequest();
// populate Request from input parameters ...
BetfairService.BeginXXX( Request, XXXCallback, State );
}
private void XXXCallback(IAsyncResult Result)
{
XXXResponse Response = BetfairService.EndXXX(Result);
if (Response.ErrorCode == XXXErrorCode.OK)
// store data from Response
else
// deal with error
}
public void DoXXX()
{
XXXRequest=新的XXXRequest();
//从输入参数填充请求。。。
betfailservice.BeginXXX(请求,xxx回调,状态);
}
私有void XXXCallback(IAsyncResult结果)
{
XXXResponse-Response=BetfairService.EndXXX(结果);
if(Response.ErrorCode==XXXErrorCode.OK)
//存储来自响应的数据
其他的
//处理错误
}
我想执行一组指定的命令,然后在所有命令完成后,使用组合返回的数据值进行一些计算
我可以按顺序执行此操作,方法是创建一个命令队列,让每个回调方法在完成后触发队列中的下一个命令,并将计算作为队列中的最后一项。然而,这是相对缓慢的
我的理想解决方案是让所有这些命令并行运行,然后在所有命令完成后触发计算。我试过查看Task.Factory.fromsync(),但我能找到的所有示例都只包括对BeginXXX/EndXXX的直接调用,而没有对响应执行任何操作
是否有人有任何针对此问题的合适解决方案的指针?要使用
fromsync
,您需要指定返回类型:
var task = Task<XXXResponse>.Factory.FromAsync( ...
var task=task.Factory.fromsync(。。。
然后,您将有一个任务,其结果
属性类型为XXXResponse
然后您可以使用Parallel.Invoke
并行运行初始命令。这将阻止所有这些任务完成。然后您可以执行“附加处理”
或者,您可以将初始任务存储在一个数组中,并使用Task.Factory.continuewhalll
创建一个延续
尼克你应该有一个已执行服务调用的计数器。在每个回调方法中,你应该检查这个计数器-如果它等于服务调用的最大数量,你应该做额外的处理,否则-你只需增加计数器。我建议你看看微软的反应式扩展(Rx)它允许您将异步操作(除其他外)转换为可观察的LINQ查询 假设我有三个函数,每一个都需要花费大量的时间来计算:
Func<int> fa = () =>
{
Thread.Sleep(2000);
return 42;
};
Func<int, string, string> fb = (n, t) =>
{
Thread.Sleep(n * 1000);
return t + n.ToString();
};
Func<DateTimeOffset> fc = () =>
{
Thread.Sleep(1000);
return DateTimeOffset.UtcNow;
};
现在,我只需执行以下操作即可启动所有呼叫:
IObservable<int> oa = ofa();
IObservable<string> ob = ofb(1, "foo");
IObservable<DateTimeOffset> oc = ofc();
然后我订阅此查询以获得结果:
query.Subscribe(p =>
{
Console.WriteLine(p.a);
Console.WriteLine(p.b);
Console.WriteLine(p.c);
});
在我的测试中,我在这段代码周围放置了计时器来计算实际的执行时间。即使如果以串行方式运行,那么总时间应该是4秒,但这段代码在2分钟内完成——这是三个时间中的最长时间
现在这个例子只是Rx可以做的一个小方面,但它是一个很好的起点
如果我能进一步解释的话,大声喊出来
以下是Rx的链接:
Task.Factory.fromsync
返回的任务应该在EndXXX
方法完成后才能完成eted.continuewheall
还返回一个Task
对象,您可以对其执行所有正常的任务操作,如Wait()
。实际上这是我的错误。我正在为WPF开发,因此所有可能更新绑定属性的内容都包装在CurrentDispatcher.BeginInvoke()中-这就是导致我的排序问题的原因。任务不需要这样做,而且一切正常。谢谢提示。
var query =
from a in oa
from b in ob
from c in oc
select new { a, b, c };
query.Subscribe(p =>
{
Console.WriteLine(p.a);
Console.WriteLine(p.b);
Console.WriteLine(p.c);
});