[在List <>。ForEach方法调用中的LINQ表达式中使用时等待,不等待

问题描述 投票:1回答:2

我有一个异步函数,在其中必须对列表的每个元素进行异步调用。为此,我编写了这段代码:

List<string> batchItems;

batchItems.ForEach(async t => await SubmitBatchItemAsync(input, t));

但是,这不起作用:SubmitBatchItemAsync被调用,但是未等待。

为了使它正常工作,我不得不对此代码进行更改:

List<string> batchItems;
foreach (var batchItem in batchItems)
    {
        await SubmitBatchItemAsync(input, batchItem);
    }

这也可以,但是不完全一样,因为Task.Wait()不能完全像await一样工作:

List<string> batchItems;

batchItems.ForEach(t => SubmitBatchItemAsync(input, t).Wait(CancellationToken.None));

有人知道为什么第一个选项不起作用,因为LINQ表达式支持等待吗? (https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/statements-expressions-operators/lambda-expressions#async-lambdas

c# foreach async-await wait
2个回答
4
投票

ForEach不支持async。仅需要Action即可对可枚举的每个项目执行。

因此,这意味着您的lambda表达式async t => await SubmitBatchItemAsync(input, t)正像通常那样被转换为Func<T, Task>;它正被转换为Action<T>,强制为async voidpitfalls of async void methods之一是调用代码无法轻松确定何时完成。

TL; DR:有些API不支持async void,在处理异步代码时应避免使用。 async是这些API之一。


0
投票
您可能会发现此扩展方法对ForEach有用:
© www.soinside.com 2019 - 2024. All rights reserved.