任何指向List. foreach()的Async

本文关键字:Async foreach List 任何指 | 更新日期: 2023-09-27 18:07:24

我碰到了这段代码:

items.ForEach(async item =>
{
     doSomeStuff();   
     await mongoItems.FindOneAndUpdateAsync(mongoMumboJumbo);
     await AddBlah(SqlMumboJumbo);
});

让它成为一个。foreach委托是否有任何意义,或者它只是一个普通的foreach循环?只要包含循环的函数是异步的,这将是默认的异步?

任何指向List<T>. foreach()的Async

ForEach接收到的委托是Action<T>:

public void ForEach(Action<T> action)

这意味着,你在它里面使用的任何异步委托将有效地变成一个async void方法。这是一种"立即走人"的执行方式。这意味着你的foreach在继续对列表中的下一个项目调用委托之前不会异步等待完成,这可能是一个不希望的行为。

使用常规的foreach

边注- foreach VS foreach by Eric Lippert,很棒的博客文章

您不知道函数何时完成,也不知道函数的结果。如果在单独的Task中启动每个计算,则可以等待Task。并解释结果,甚至捕获异常:

private async Task ActionAsync(T item)
{
    doSomeStuff();   
    await mongoItems.FindOneAndUpdateAsync(mongoMumboJumbo);
    await AddBlah(SqlMumboJumbo);
}
private async Task MyFunction(IEnumerable<T> items)
{
    try
    {
        foreach (var item in items)
        {
            tasks.Add( ActionAsync(item) )
        }
        // while all actions are running do something useful
        // when needed await for all tasks to finish:
        await Task.WhenAll(tasks);
        // interpret the result of each action using property Task.Result
    }
    catch (AggregateException exc)
    {
        ProcessAggregateException(exc);
    }
}

当您的任何任务抛出异常时,将抛出aggregateException。如果包含所有任务抛出的所有异常