39

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

    await someCall();
    await anotherCall();

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

async是否可以仅使用and await(不使用旧begin/end机制)来实现此场景?

4

3 回答 3

53

async/await 包含一些有助于并行组合的运算符,例如WhenAlland WhenAny

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;
于 2011-08-30T13:58:18.620 回答
7

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

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

如果您想要结果值,这尤其好:

var result = await taskA + await taskB;

所以你不需要这样做 taskA.Result

TaskEx.WhenAll可能比两个相互等待要快。我不知道,因为我还没有对此进行性能调查,但是除非您发现问题,否则我认为连续两次等待会更好,尤其是在您想要结果值的情况下。

于 2012-01-18T20:33:27.977 回答
2

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

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

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

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;
于 2014-03-26T13:39:16.657 回答