Task.WhenAll用较少的代码行

时间:2016-07-20 07:09:03

标签: c# asynchronous

使用Comparator有很多好处,但它至少会使写东西所需的LOC加倍。

清单1

Task.WhenAll

Listing2

var result1 = await SomeLongRunningOperation1().ConfigureAwait(false);
var result2 = await SomeLongRunningOperation2().ConfigureAwait(false);
var result3 = await SomeLongRunningOperation3().ConfigureAwait(false);

显然,Listing1一个接一个地等待3个操作(3 x 10秒= 30秒),而Listing2同时等待3个操作(所有3个操作只有10秒)。

然而,清单2中的代码更难以阅读。

我的问题是: 是否可以使用易于阅读和与清单1一样简短的内容编写清单2的逻辑?

3 个答案:

答案 0 :(得分:1)

正如我在评论中所说,这实现了您正在寻找的并行性,并使用比清单2更少的代码行:

+-------+
| id    |
+-------+
| 23129 |
| 23482 |
| 23483 |
| 23915 |
| 24274 |
| 24417 |
  ...
| 34855 |
+-------+

它在时间方面确实存在细微差别 - 如果在var result1Task = SomeLongRunningOperation1(); var result2Task = SomeLongRunningOperation2(); var result3Task = SomeLongRunningOperation3(); var result1 = await result1Task.ConfigureAwait(false); var result2 = await result2Task.ConfigureAwait(false); var result3 = await result3Task.ConfigureAwait(false); result1可用之前result2显着可用,则会在之前提前签署。但是,由于您result3完成了所有3项任务(并且不对结果做任何事情),因此在完成所有三项任务之前,您实际上无法继续完成await的任务 - 您result3要求的内容。

答案 1 :(得分:0)

你可以使用Tuple,但你必须为各种arities构建帮助方法。这里有3个参数:

public static async Task<Tuple<T1, T2, T3>> WhenAll<T1, T2, T3>(Task<T1> t1, Task<T2> t2, Task<T3> t3)
{
    await Task.WhenAll(t1, t2, t3).ConfigureAwait(false);
    var result1 = await t1.ConfigureAwait(false);
    var result2 = await t2.ConfigureAwait(false);
    var result3 = await t3.ConfigureAwait(false);
    return Tuple.Create(result1, result2, result3);
}

用法:

var results = await WhenAll(Operation1(), Operation2(), Operation3());
var result1 = results.Item1;

在C#7中,您可以使用内置的元组支持,以便命名元组项。

答案 2 :(得分:0)

如果您的操作都具有相同的结果类型,您也可以这样做:

var task1 = SomeLongRunningOperation1();
var task2 = SomeLongRunningOperation2();
var task3 = SomeLongRunningOperation3();

var results = await Task.WhenAll(task1, task2, task3).ConfigureAwait(false);