异步/等待循环行为

时间:2018-03-10 12:35:36

标签: c# asynchronous async-await

假设我有一个算法列表,每个算法在该算法的主体中包含一个异步调用。我执行算法的顺序是我想要接收结果的顺序。也就是说,在所有算法执行完毕后,我希望AlgorithmResult List看起来像{Algorithm1Result,Algorithm2Result,Algorithm3Result}。我是否正确地说,如果Algorithm1和3在2之前完成,我的结果实际上将按照{Algorithm1Result,Algorithm3Result,Algorithm2Result}的顺序

var algorithms = new List<Algorithm>(){Algorithm1, Algorithm2, Algorithm3};
var algorithmResults = new List<AlgorithmResults>();

  foreach (var algorithm in algorithms)
  {
     algorithmResults.Add(await algorithm.Execute());
  }

2 个答案:

答案 0 :(得分:1)

否,结果与您将其添加到列表的顺序相同,因为每个操作都是单独等待的。

class Program
{
    public static async Task<int> GetResult(int timing)
    {
        return await Task<int>.Run(() =>
        {
            Thread.Sleep(timing * 1000);
            return timing;
        });
    }

    public static async Task<List<int>> GetAll()
    {
        List<int> tasks = new List<int>();

        tasks.Add(await GetResult(3));
        tasks.Add(await GetResult(2));
        tasks.Add(await GetResult(1));

        return tasks;
    }

    static void Main(string[] args)
    {
        var res = GetAll().Result;
    }
}

res无论如何都包含了添加顺序的列表,这也不是并行执行。

答案 1 :(得分:0)

由于您没有添加任务,但是等待后的任务结果,它们将按您想要的顺序添加。

即使您在添加下一个任务之前没有等待结果,您也可以获得所需的订单:

以小步骤显示类型感知:

List<Task<AlgorithmResult>> tasks = new List<Task<AlgorithmResult>>();
foreach (Algorithm algorithm in algorithms)
{
    Task<AlgorithmResult> task = algorithm.Execute();

    // don't wait until task Completes, just remember the Task
    // and continue executing the next Algorithm
    tasks.Add(task);
}

现在有些任务可能正在运行,有些可能已经完成。让我们等到它们全部完成,然后获取结果:

Task.WhenAll(tasks.ToArray());
List<AlgrithmResults> results = tasks.Select(task => task.Result).ToList();