使用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的逻辑?
答案 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);