假设我有一个C#控制器调用一些返回Task的任意函数(例如,因为它执行数据库事务).我应该总是使用异步和等待,还是应该只返回任务?
示例控制器:
public async Task<string> DoSomething() {
return await SomeOtherFunctionThatReturnsATask();
}
Run Code Online (Sandbox Code Playgroud)
我应该把它改成:
public Task<string> DoSomething() {
return SomeOtherFunctionThatReturnsATask();
}
Run Code Online (Sandbox Code Playgroud)
还是真的没关系?
Cod*_*lla 23
是的,您应该更改方法并删除async/await.该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");
}
Run Code Online (Sandbox Code Playgroud)
你可以看到我所指的第一个状态机.它将无缘无故地做所有等待的工作,然后最终的消费者DoSomething()将重复同样的工作.实际上,只有await当方法中的其他代码需要在返回任务的代码之后运行时,才应该真正使用关键字.因为该代码需要等待它在运行之前完成.
完整的反编译代码:http://pastebin.com/iJLAFdHZ
| 归档时间: |
|
| 查看次数: |
2230 次 |
| 最近记录: |