首页 > 解决方案 > 在 foreach 中同步调用异步

问题描述

我有像这样定义 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 是异步方法

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

标签: c#

解决方案


只需添加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完成,您可以这样做(不需要异步或等待):

Task.WhenAll(requests.Select(x => client.callAsync(x)).Wait();

虽然它们听起来很相似,await并且Task.Wait在概念上是非常不同的东西。总之,前者是非阻塞的,后者是阻塞的。


推荐阅读