c# - 我们可以将异步方法转换为表达式主体吗?

标签 c# asynchronous async-await c#-6.0

我在看 this关于C#6.0中Expression Bodied Members的文章,作者演示了这段代码:

public async Task<string> ReadFromWeb() => await RunWebRequest();

他说不推荐使用asyncawait上面代码中的关键字:

The compiler is performing some heavy lifting to implement the async state machine for this method. Because of the structure of the method, that extra work isn't really accomplishing much. It's creating a state machine to wrap a task that simply unwraps a task returned from a different method. He proposed that we should write the code without async and await:


public Task<string> ReadFromWebSimple() => RunWebRequest();

我想了解更多相关信息。

最佳答案

让我们看看作者在说什么。当您将方法标记为 async 时,编译器代表您生成一个状态机,以允许异步执行风格“感觉”它正在同步执行。

当你写:

public async Task<string> ReadFromWeb() => await RunWebRequest();

编译器生成:
[AsyncStateMachine(typeof(C.<RunWebRequest>d__1))]
public Task<string> RunWebRequest()
{
    C.<RunWebRequest>d__1 <RunWebRequest>d__;
    <RunWebRequest>d__.<>t__builder = AsyncTaskMethodBuilder<string>.Create();
    <RunWebRequest>d__.<>1__state = -1;
    AsyncTaskMethodBuilder<string> <>t__builder = <RunWebRequest>d__.<>t__builder;
    <>t__builder.Start<C.<RunWebRequest>d__1>(ref <RunWebRequest>d__);
    return <RunWebRequest>d__.<>t__builder.Task;
}

由于您使用的是 Expression Bodied Method,因此您实际上只有一个方法的衬里。你一般什么时候做await在某事上?当你想操作异步方法的返回值 .对于单衬,情况并非如此。这意味着您可以在调用级别保存状态机生成,并且只让那些真正想要的人await结果在调用者堆栈上更高到 await在你的方法上。这将有效地将您的方法转换为如下所示:
public Task<string> ReadFromWeb()
{
    return this.RunWebRequest();
}

这为您节省了已经相当纤薄的状态机 struct由编译器分配,这在您创建 EBM 时实际上是非常多余的。

关于c# - 我们可以将异步方法转换为表达式主体吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33054199/

相关文章:

c# - 在 ASP.NET 事件处理程序中使用 async/await 是否安全?

c# - Regex.Split 加号和减号

c# - 带有私有(private)字段的 INotifyPropertyChanged

javascript - IE 中的 Ajax 异步 - 错误 "The Data Necessary to Complete This Operation is Not Yet Available"

c# - 异步,在 visual studio 2010 中等待

c# - C#异步而不创建新线程

c# - 在 C# 中找出文件所有者/创建者

c# - 如何从对话框更改 Form 1 中的内容?

asynchronous - 如何测量 Julia 中函数的@async 运行时间?

c# - 异步方法混淆