编译器是否对异步方法链执行“返回值优化”
在传统意义上没有返回值优化,但我想知道你什么时候有这样的情况:
private async Task Method1() { await Method2(); } private async Task Method2() { await Method3(); } private async Task Method3() { //do something async }
这显然可以写得更优:
private Task Method1() { return Method2(); } private Task Method2() { return Method3(); } private async Task Method3() { //do something async }
我只是想知道是否有人知道(MS)编译器是否足够聪明,不能在第一个实例中为Method1()
和Method1()
生成状态机?
不,C#编译器不优化它,它不应该 。 这些在概念上是两个不同的东西,这是一个类似的问题 。
IMO,主要区别在于exception如何被传播到Method1
和Method1
的调用者。 我在这里演示了这个行为。
在第一种情况下(没有状态机),将立即在调用者的堆栈帧上抛出exception。 如果它是unhanded,应用程序可能会立即崩溃(除非在同一堆栈帧的调用链中有另一个async
方法)。
在第二种情况下(使用状态机),exception将在返回给调用者的Task
对象中保持hibernate状态 ,直到通过await task
或task.Wait()
观察到一段时间之后。 它可能在完全不同的堆栈帧上被观察到,或者可能根本没有被观察到。 我在这里发布了一些关于此的更多细节。
你为什么要通过简单测试就能在一分钟内提出一个问题?
class Program { static void Main(string[] args) { MainAsync().Wait(); Console.ReadLine(); } static async Task MainAsync() { await Method1(); } static async Task Method1() { await Method2(); } static async Task Method2() { await Method3(); } static async Task Method3() { Console.Write("Start"); await Task.Delay(1000); Console.Write("End"); } }
这在IL中创建了四个不同的状态机。
IL代码必须是这种方式,因为您可以从任何地方调用方法,并且它们必须一致地运行,因此任何优化都必须在JIT级别上完成,而不是C#编译器。 如果您不需要await
,请不要使用它 – 这是您的责任。
一个很好的例子是方法重载:
static Task Method() { return Method("Default"); } static async Task Method(string someString) { await SomeThingAsync(someString); }
它仍然像在无参数方法中做另一个等待一样异步 – 但它避免了无用的状态机。
async
关键字的唯一目的是允许您在给定方法中使用await
关键字。 您仍然可以await
非async
的方法 – 要求是返回Task
,而不是async
关键字。
使用与以前相同的示例, await
s是多余的。 一个更简单的方法是:
上述就是C#学习教程:编译器是否对异步方法链执行“返回值优化”分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
class Program { static void Main(string[] args) { MainAsync().Wait(); Console.ReadLine(); } static async Task MainAsync() { await Method1(); await Method2(); } static Task Method1() { return Method2(); } static Task Method2() { return Method3(); } static async Task Method3() { Console.Write("Start"); await Task.Delay(1000); Console.Write("End"); } }
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1022870.html