在异步方法中消除异步并等待

编程入门 行业动态 更新时间:2024-10-25 18:32:18
本文介绍了在异步方法中消除异步并等待的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

一个简单的问题;阅读本文: blog.stephencleary/2016/12/eliding-async-await.html

a quick question; reading this article: blog.stephencleary/2016/12/eliding-async-await.html

它通常告诉我,请使用async/await.已经准备好了.但是,他还说代理任务时不必使用异步部分.

it generally tells me, use async/await. Allready doing that. However, he is also saying that you don't have to use the async part when you are proxying the task.

// Simple passthrough to next layer: elide. Task<string> PassthroughAsync(int x) => _service.DoSomethingPrettyAsync(x); // Simple overloads for a method: elide. async Task<string> DoSomethingPrettyAsync(CancellationToken cancellationToken) { ... // Core implementation, using await. }

为什么通过时不应该使用async/await?难道不是那么方便,这是否有意义?

why should be not use async/await when passing through? Isn't that less convenient, and does this even make sense?

有人有什么想法吗?

推荐答案

为什么通过时不应该使用async/await?

why should be not use async/await when passing through?

由于您键入await的那一刻,编译器添加了 ton 的实现胶,该胶完全对您没有任何作用-调用方已经可以等待被代理的任务.

because the moment you type await, the compiler adds a ton of implementation glue that does absolutely nothing for you - the caller can already just await the proxied task.

如果我添加类似您的PassthroughAsync的内容,但添加async/await:

If I add something like your PassthroughAsync, but with the async/await:

async Task<string> AwaitedAsync(int x) => await DoSomethingPrettyAsync(x);

然后我们可以通过编译并反编译IL来查看庞大但完全冗余的代码:

then we can see the huge but completely redundant code by compiling it and decompiling the IL:

[AsyncStateMachine(typeof(<AwaitedAsync>d__1))] private Task<string> AwaitedAsync(int x) { <AwaitedAsync>d__1 <AwaitedAsync>d__ = default(<AwaitedAsync>d__1); <AwaitedAsync>d__.<>4__this = this; <AwaitedAsync>d__.x = x; <AwaitedAsync>d__.<>t__builder = AsyncTaskMethodBuilder<string>.Create(); <AwaitedAsync>d__.<>1__state = -1; AsyncTaskMethodBuilder<string> <>t__builder = <AwaitedAsync>d__.<>t__builder; <>t__builder.Start(ref <AwaitedAsync>d__); return <AwaitedAsync>d__.<>t__builder.Task; } [StructLayout(LayoutKind.Auto)] [CompilerGenerated] private struct <AwaitedAsync>d__1 : IAsyncStateMachine { public int <>1__state; public AsyncTaskMethodBuilder<string> <>t__builder; public C <>4__this; public int x; private TaskAwaiter<string> <>u__1; private void MoveNext() { int num = <>1__state; C c = <>4__this; string result; try { TaskAwaiter<string> awaiter; if (num != 0) { awaiter = c.DoSomethingPrettyAsync(x).GetAwaiter(); if (!awaiter.IsCompleted) { num = (<>1__state = 0); <>u__1 = awaiter; <>t__builder.AwaitUnsafeOnCompleted(ref awaiter, ref this); return; } } else { awaiter = <>u__1; <>u__1 = default(TaskAwaiter<string>); num = (<>1__state = -1); } result = awaiter.GetResult(); } catch (Exception exception) { <>1__state = -2; <>t__builder.SetException(exception); return; } <>1__state = -2; <>t__builder.SetResult(result); } void IAsyncStateMachine.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext this.MoveNext(); } [DebuggerHidden] private void SetStateMachine(IAsyncStateMachine stateMachine) { <>t__builder.SetStateMachine(stateMachine); } void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine) { //ILSpy generated this explicit interface implementation from .override directive in SetStateMachine this.SetStateMachine(stateMachine); } }

现在与非async passthru编译为的内容形成对比:

Now contrast to what the non-async passthru compiles to:

private Task<string> PassthroughAsync(int x) { return DoSomethingPrettyAsync(x); }

除了绕过大量的struct初始化和方法调用之外,如果实际上是异步的,则可能在堆上出现一个盒子"(在已经完成同步的情况下不是盒子"),该PassthroughAsync还将非常适合进行JIT内联,因此在实际的CPU操作码中,PassthroughAsync可能甚至不存在.

In addition to bypassing a huge amount of struct initialization and method calls, a possible "box" onto the heap if it is actually async (it doesn't "box" in the already-completed-synchronously case), this PassthroughAsync will also be a great candidate for JIT-inlining, so in the actual CPU opcodes, PassthroughAsync will probably not even exist.

更多推荐

在异步方法中消除异步并等待

本文发布于:2023-11-12 18:57:52,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1582277.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:方法

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!