在lambda循环中的异步调用没有等待。

3
我有一个方法,它在完成之前返回(为简洁起见,已缩减下列代码):

private void ProcessAllItems(List<Item> items)
{
    items.ForEach(async item =>
    {
        var response = await Processor.IOBoundTaskAsync(item);
        // Some further processing on the response object.
    });
}

Processor.IOBoundTaskAsync 方法返回一个 Task<SomeResponseObject>,而不是 void。
发生了什么?
我希望 lambda foreach 每次只处理一个项目,而不是并行处理。对于第一次迭代,代码进入 IOBoundTaskAsync 并走到第一个 "await" (它调用了 4 个等待的 web 服务方法中的第一个) ,然后调用方法 "ProcessAllItems" 就退出了。
我只使用测试数据,所以我的列表中只有一个项目。
我错过了什么?
1个回答

8

List<T>.ForEach 方法将您的异步 lambda 转换为 async void,因为它接受一个 Action<T>。虽然它确实执行了这个操作,并且它在异常处理方面有一些复杂性,但是您的 ForEach 调用应该正常工作。如果没有,请检查您是否正确使用了异步模式。建议您在第一个 await 后设置断点并查看继续执行情况。

我建议您改用普通的 foreach

private async Task ProcessAllItemsAsync(List<Item> items)
{
    foreach (var item in items)
    {
       var response = await Processor.IOBoundTaskAsync(item);
       // Some further processing on the response object.
    }
}

阅读如何在ForEach中使用Async?以获取更多信息。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接