首页 > 解决方案 > 等待一系列任务按顺序运行

问题描述

我想创建一个通用方法来等待一系列任务按顺序完成,检索每个任务的结果。这是我创建的代码:

public static class TaskMixin 
{
    public static async Task<IEnumerable<T>> AwaitAll<T>(this IEnumerable<Task<T>> tasks)
    {
        var results = new List<T>();
        foreach (var t in tasks)
        {
            results.Add(await t);
        }

        return results;
    }
}

有更好的或内置的方法吗?

注意

在编写上述方法之前,我尝试过使用内置Task.WhenAll方法,但这给我带来了麻烦,因为这些任务使用的是实体框架DbContext,而且它们似乎是同时运行的。

这是我使用Task.WhenAll.

在前一个异步操作完成之前在此上下文上启动了第二个操作

标签: c#.netconcurrencyasync-await

解决方案


无法确保传递给此方法的任务尚未运行,实际上它们可能已经启动了热任务。如果任务已经在运行,那么您只需按顺序等待它们。如果您希望操作按顺序运行,那么您需要调用按顺序返回任务的方法。

或者在 EF 的情况下,DbContext通常最好DbContext为每个请求使用一个新的。但是,如果您执行许多并行查询,那么您可能会以错误的方式解决问题。许多并行查询并不一定意味着您的查询会运行得更快。

Func<Task<T>>但是,您可以通过这样的委托来按顺序抽象出正在运行的操作:

public async Task<IEnumerable<T>> RunSequentiallyAsync<T>(Func<Task<T>>[] operations)
{
    var results = new List<T>();
    foreach (var op in operations)
    {
        results.Add(await op());
    }
    return results;
}

推荐阅读