C#异步/等待适当的结构来同时执行多个方法

时间:2018-08-21 17:14:44

标签: c# async-await task

几年前,我第一次实施异步/等待有点停滞。我在这个网站上得到了我的问题的答案,然后我以一种快乐的方式走了。

但是最近,我大声说“这不是并行运行这些调用”,尽管它与我之前收到的确切解决方案非常接近。

现在我有第二个想法。

这里是背景和可能的解决方法。

整个问题是我不想执行方法1,等待结果,然后执行方法2,然后等待那些结果。当两个方法调用彼此无关时,这太慢了。

我想执行两个方法调用,这两个方法都碰巧要去数据库,但是可以是任何东西,并且我不希望继续处理,直到得到两个调用的结果为止。

public async Task<DataViewModel> GetDataInParallel()
{
    var asyncStuff = new
    {
        result1 = await _databaseRepo.QuerySomething(),
        result2 = await _databaseRepo.QuerySomethingElse()
    };

    return new DataViewModel(asyncStuff.result1, asyncStuff.result2);
}

vs

public async Task<DataViewModel> GetDataInParallel()
{
    var result1Task = _databaseRepo.QuerySomething();
    var result2Task = _databaseRepo.QuerySomethingElse();

    var asyncStuff = new
    {
        result1 = await result1Task,
        result2 = await result2Task
    };

    return new DataViewModel(asyncStuff.result1, asyncStuff.result2);
}

我在网站上同时使用了这两个版本,但是现在我想知道使用选项1的版本是否不是并行运行,并且性能下降。

我不确定如何证明这一点;有谁知道哪个版本可以并行执行两个方法调用?还是他们都是对还是错?

1 个答案:

答案 0 :(得分:2)

第一个版本在开始第二个操作之前会等待第一个操作,因此它不是并行的。

第二个版本确实并行运行它们(先启动,然后等待)。您可以使用Task.WhenAll使它更加明显:

public async Task<DataViewModel> GetDataInParallel()
{
    var result1Task = _databaseRepo.QuerySomething();
    var result2Task = _databaseRepo.QuerySomethingElse();

    await Task.WhenAll(result1Task, result2Task);

    return new DataViewModel(result1Task.Result, result2Task.Result);
}

看看为什么WhenAll是更好的选择: Why should I prefer single 'await Task.WhenAll' over multiple awaits?