Should I use async/await for every method that returns a Task

≯℡__Kan透↙ 提交于 2020-12-01 09:01:10

问题


Suppose I have a C# controller that calls into some arbitrary function that returns a Task (for instance because it performs a database transaction). Should I always use async and await, or should I just return the task?

Example controller:

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

Should I change this into:

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

Or does it really not matter?


回答1:


Yes, you should change the method and remove the async/await. The async keyword causes the compiler to create a state machine that manages the 'waiting' for the task to complete. When you await another function like that, you're essentially creating two of these state machines which is unnecessary. It's much better to just return the task from the second function directly and allow the final consumer of the task to do the waiting.

The best way to understand this, is to write a small sample program and decompile it. Make sure your decompiler is showing you all the compiler generated stuff (which some hide by default) and you will be able to see what all is going on there.

Here's a quick example I just whipped up and used dotPeek to decompile:

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");
}

You can see the state machine in the first one that I was referring to. It's going to do all that work of await'ing for no reason, and then the final consumer of DoSomething() is going to repeat that same work. Realistically you should only really use the await keyword when there is other code in the method that needs to be run after the code that returns the task. Because that code needs to await for it to complete before it runs.

Full decompiled code here: http://pastebin.com/iJLAFdHZ



来源:https://stackoverflow.com/questions/35201881/should-i-use-async-await-for-every-method-that-returns-a-task

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!