C# 在列表中的LINQ表达式中使用WAIT not WAIT。ForEach方法调用
我有一个异步函数,其中必须对列表中的每个元素进行异步调用。为此,我编写了以下代码:C# 在列表中的LINQ表达式中使用WAIT not WAIT。ForEach方法调用,c#,foreach,async-await,wait,C#,Foreach,Async Await,Wait,我有一个异步函数,其中必须对列表中的每个元素进行异步调用。为此,我编写了以下代码: List<string> batchItems; batchItems.ForEach(async t => await SubmitBatchItemAsync(input, t)); 但是,这不起作用:SubmitBatchItemAsync被调用,但不等待 我必须将此代码更改为以下代码才能正常工作: List<string> batchItems; foreach (var
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的工作方式与Wait的工作方式不完全相同:
List<string> batchItems;
batchItems.ForEach(t => SubmitBatchItemAsync(input, t).Wait(CancellationToken.None));
有谁知道为什么第一个选项不起作用,因为LINQ表达式支持正在等待 ForEach不支持异步。它只对可枚举项的每个项执行一个操作
这意味着lambda表达式async t=>await SubmitBatchItemAsyncinput,t没有像通常那样被转换成Func;它正在转换为一个动作,强制它为异步void
其中一个原因是调用代码无法轻松确定它们何时完成
TL;DR:有些API不支持异步,在处理异步代码时应该避免使用。ForEach就是这些API之一。ForEach不支持异步。它只对可枚举项的每个项执行一个操作
这意味着lambda表达式async t=>await SubmitBatchItemAsyncinput,t没有像通常那样被转换成Func;它正在转换为一个动作,强制它为异步void
其中一个原因是调用代码无法轻松确定它们何时完成
TL;DR:有些API不支持异步,在处理异步代码时应该避免使用。ForEach是这些API之一。您可能会发现此扩展方法对列表很有用:
TBH这并不像看上去那么有用,因为在处理异步操作时,您通常希望以某种程度的并发性启动它们,而不是在完成另一个之后启动它们。您可能会发现这种扩展方法对列表很有用: TBH这并不像看上去那么有用,因为在处理异步操作时,您通常希望以某种程度的并发性启动它们,而不是在完成另一个操作之后启动它们
public static async Task ForEachAsync<T>(this List<T> source, Func<T, Task> function)
{
foreach (var item in source)
{
await function(item);
}
}
await batchItems.ForEachAsync(async t => await SubmitBatchItemAsync(input, t));