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

Roy*_*mir 9 c# task async-await c#-5.0 .net-4.5

所以我问这个问题有关async,我认为它,它只是一个语法糖为:

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

最后检查Result财产.

我甚至在这里问了一个问题,我被告知:

在此输入图像描述

在此输入图像描述

但今天我被Jon Skeet纠正了

"这距离很远很远".

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

Jon*_*eet 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;
}
Run Code Online (Sandbox Code Playgroud)

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

接下来,如果您需要等效的方法中的try/ finally,请弄清楚如何更改代码async.同样,这将使非异步方法更复杂.这一切都可以完成,但这是一个痛苦的问题.

所以,是的,这只是"正义"的句法糖.也是foreach.所以是一个for循环(或任何其他类型的循环).在async/ 的情况下await,它的语法糖可以用来转换你的代码.

许多关于异步的视频和博客文章,我希望只是观看/阅读其中的一些会让你有足够的洞察力来欣赏这远远不是一个小小的调整:它从根本上改变了写大的实用性正确的异步代码量.

另外,基于模式,async/await 不仅适用于Task/ Task<T>.你可以等待任何符合等待模式的东西.在实践中,很少有开发人员需要自己实现模式,但它允许Task.Yield返回一个YieldAwaitable而不是一个任务的方法.

  • @hVostt:我已经反编译*lot*async/await代码.我不会再对这种差异感到惊讶,但我仍然认为这只是"只是"语法糖.它是非常有用且相当复杂的语法糖,有时结果是代码无法用*完全*表示IL使用C#4 - 但从根本上说它没有做任何以前真的无法做到的事情.它不像泛型,这是类型系统的根本转变.这只是编译器的智能.我不是要低估它有多么有用 - 我喜欢*异步.但它仍然是语法糖IMO. (3认同)