c# – 对于返回任务的每个方法,我应该使用async / await

假设我有一个C#控制器调用一些返回任务的任意函数(例如因为它执行一个数据库事务).我应该永远使用异步和等待,还是应该只返回任务?

示例控制器

public async Task<string> DoSomething() {
    return await SomeOtherFunctionThatReturnsATask();
}

我应该把它改成:

public Task<string> DoSomething() {
    return SomeOtherFunctionThatReturnsATask();
}

还是真的没关系?

解决方法

是的,您应该更改方法删除异步/等待. async关键字使编译器创建一个状态机来管理任务完成的“等待”.当你等待另外一个这样的功能的时候,你本质上就是创建两个不必要的状态机.最好直接从第二个函数返回任务,并允许任务的最终使用者进行等待.

理解这一点的最好方法是编写一个小样本程序并对其进行反编译.确保您的反编译器显示所有编译器生成的东西(认情况下隐藏),您将可以看到所有的内容.

这是一个快速的例子,我刚刚鞭打,并使用dotpeek反编译:

public Task<string> DoSomething()
{
  Class1.\u003CDoSomething\u003Ed__0 stateMachine;
  stateMachine.\u003C\u003E4__this = this;
  stateMachine.\u003C\u003Et__builder = AsyncTaskMethodBuilder<string>.Create();
  stateMachine.\u003C\u003E1__state = -1;
  stateMachine.\u003C\u003Et__builder.Start<Class1.\u003CDoSomething\u003Ed__0>(ref stateMachine);
  return stateMachine.\u003C\u003Et__builder.Task;
}

private Task<string> DoSomethingElse()
{
  return Task.Fromresult<string>("test");
}

你可以看到我所指的第一个状态机.这样做的所有工作都将无缘无故地等待,然后DoSomething()的最终消费者将重复同样的工作.实际上,如果需要在返回任务的代码后运行该方法中的其他代码,那么您应该只能真正使用await关键字.因为该代码在运行之前需要等待完成.

完整的反编译代码在这里http://pastebin.com/iJLAFdHZ

相关文章

在要实现单例模式的类当中添加如下代码:实例化的时候:frmC...
1、如果制作圆角窗体,窗体先继承DOTNETBAR的:public parti...
根据网上资料,自己很粗略的实现了一个winform搜索提示,但是...
近期在做DSOFramer这个控件,打算自己弄一个自定义控件来封装...
今天玩了一把WMI,查询了一下电脑的硬件信息,感觉很多代码都...
最近在研究WinWordControl这个控件,因为上级要求在系统里,...