c#5异步作为糖语法(或不)?

时间:2013-06-29 19:49:03

标签: c# task .net-4.5 async-await c#-5.0

所以我问this question关于async,我认为它只是一个糖语法:

Task<..>...ContinueWith...

最后检查Result属性。

我甚至问了一个关于它的问题here我被告知:

enter image description here

enter image description here

但今天I was corrected by Jon Skeet

“距离那里还有很长的路要走。”

那么这两种方法之间的核心差异是什么?

1 个答案:

答案 0 :(得分:15)

添加延续 - 但是由于需要随身携带有关我们所处的位置以及本地状态的所有信息,因此手动构建该延续可能会非常痛苦。

作为非常的简单示例,我建议您尝试提供相同的异步方法:

public static async Task<int> SumTwoOperationsAsync()
{
    var firstTask = GetOperationOneAsync();
    var secondTask = GetOperationTwoAsync();
    return await firstTask + await secondTask;
}

// These are just examples - you don't need to translate them.
private async Task<int> GetOperationOneAsync()
{
    await Task.Delay(500); // Just to simulate an operation taking time
    return 10;
}

private async Task<int> GetOperationTwoAsync()
{
    await Task.Delay(100); // Just to simulate an operation taking time
    return 5;
}

真的尝试提出相当于第一种方法。我想你会发现它需要相当多的代码 - 尤其是如果你真的想每次都回到适当的线程。 (想象一下,async方法中的代码也修改了WPF UI。)哦,并确保如果任一任务失败,您返回的任务也会失败。 (如果第一个任务也失败了,async方法实际上会“错过”第二个任务的失败,但这是一个相对较小的问题IMO。)

接下来,如果您需要在try方法中使用finally / async,则需要了解如何更改代码。再次,这将使非异步方法更复杂。这一切都可以完成,但这是一个痛苦的问题。

所以是的,它只是“只是”语法糖。 foreach也是如此。所以是for循环(或任何其他类型的循环)。在async / await的情况下,它的语法糖可以在转换代码方面做很多事情。

很多的视频和博客帖子都是异步的,我希望只是观看/阅读其中的一些内容会让你有足够的洞察力来欣赏这远远不是一个小小的调整: 从根本上改变了正确编写大量异步代码的实际可行性。

此外,基于模式,async / await不会Task / Task<T>上工作。你可以等待任何符合等待模式的东西。在实践中,很少有开发人员需要自己实现模式,但它允许像Task.Yield这样的方法返回YieldAwaitable而不是任务。