使用await进行多个并行异步调用

时间:2011-05-12 07:21:13

标签: asynchronous multitasking async-await c#-5.0

据我所知,当运行时遇到下面的语句时,它将函数的其余部分包装为异步调用的方法的回调(在本例中为someCall())。在这种情况下,anotherCall()将作为someCall()的回调执行:

    await someCall();
    await anotherCall();

我想知道是否有可能使运行时执行如下:以异步方式调用someCall()并立即返回调用线程,然后类似地调用anotherCall()(无需等待someCall完成)。因为我需要这两种方法异步运行,并假设这些调用只是激活而忘记调用。

是否可以仅使用asyncawait(不使用旧的begin / end机制)来实施此方案?

3 个答案:

答案 0 :(得分:49)

async / await包含一些帮助进行并行合成的运算符,例如WhenAllWhenAny

var taskA = someCall(); // Note: no await
var taskB = anotherCall(); // Note: no await

// Wait for both tasks to complete.
await Task.WhenAll(taskA, taskB);

// Retrieve the results.
var resultA = taskA.Result;
var resultB = taskB.Result;

答案 1 :(得分:6)

最简单的方法可能是这样做:

var taskA = someCall();
var taskB = someOtherCall();
await taskA;
await taskB;

如果你想要结果值,这个特别好:

var result = await taskA + await taskB;

因此您无需执行taskA.Result

TaskEx.WhenAll可能比两个等待更快。我不知道,因为我没有对此进行过性能调查,但除非你看到一个问题,否则我认为连续两次等待更好,特别是如果你想要结果值。

答案 2 :(得分:2)

如果您使用的是.NET 4.5,则不再需要Async CTP。请注意,异步功能由编译器实现,因此.NET 4应用程序可以使用它,但编译它需要VS2012。

不再需要TaskEx。 CTP无法修改现有框架,因此它使用扩展来完成语言在5.0中处理的事情。只需直接使用Task。

因此,我重新编写了代码(由Stephen Cleary回答),将TaskEx替换为Task。

var taskA = someCall(); // Note: no await
var taskB = anotherCall(); // Note: no await

// Wait for both tasks to complete.
await Task.WhenAll(taskA, taskB);

// Retrieve the results.
var resultA = taskA.Result;
var resultB = taskB.Result;