为eacheach同步调用异步

时间:2019-03-01 14:32:41

标签: c#

我的外部库具有如下定义的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是异步方法

我应该创建任务列表,然后等待所有任务,还是有更好的方法?

2 个答案:

答案 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();

虽然它们听起来很相似,但是awaitTask.Wait在概念上是完全不同的。简而言之,前者是非阻塞的,后者是阻塞的。

答案 1 :(得分:1)

如果您需要等到所有任务完成后再返回,那么我认为没有比创建任务列表并等待所有方法更好的方法了。例如

Task.WaitAll(requests.Select(x => Task.Run(async (x) => await client.callAsync(x)));

以上代码将在单独的线程上运行每个任务,然后阻塞主线程,直到所有任务结束。