我的外部库具有如下定义的eventCallback:
public delegate void processEvent(string deviceType, string deviceId,string evtName, string format, string data);
// event for event callback
public event processEvent eventCallback;
在我的代码中,我以此方式订阅了此事件
app.eventCallback += ProcessEvent;
protected void ProcessEvent(string deviceType, string deviceId, string eventName, string format, string data)
{
var requests = GetRequests();
foreach (var serviceRequest in requests)
{
client.callAsync(serviceRequest)
}
}
问题是如何调用client.callAsync
异步?
我无法更改ProcessEvent
的签名以返回Task,因为那时我无法将其绑定到eventCallback += ProcessEvent;
callAsync是异步方法
我应该创建任务列表,然后等待所有任务,还是有更好的方法?
答案 0 :(得分:2)
只需将async
添加到方法签名:
protected async void ProcessEvent(string deviceType, string deviceId, string eventName, string format, string data)
这有效,因为您没有更改返回类型。然后将呼叫更改为:
await client.callAsync(serviceRequest);
这里也可能要使用ConfigureAwait(false)
。
如果要一次异步运行所有服务请求,请将foreach
更改为:
await Task.WhenAll(requests.Select(x => client.callAsync(x));
或者,您可以根据需要使用一组任务。效果一样。
编写时,事件处理程序会一次执行一个请求。
如果您想在每个Task
完成时 block ,您可以执行此操作(不需要异步或等待):
Task.WhenAll(requests.Select(x => client.callAsync(x)).Wait();
答案 1 :(得分:1)
如果您需要等到所有任务完成后再返回,那么我认为没有比创建任务列表并等待所有方法更好的方法了。例如
Task.WaitAll(requests.Select(x => Task.Run(async (x) => await client.callAsync(x)));
以上代码将在单独的线程上运行每个任务,然后阻塞主线程,直到所有任务结束。