我应该对返回任务的每个方法都使用async/await吗? [英] Should I use async/await for every method that returns a Task

查看:84
本文介绍了我应该对返回任务的每个方法都使用async/await吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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?

示例控制器:

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

我应该将其更改为:

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

还是真的没关系吗?

推荐答案

是的,您应该更改方法并删除异步/等待. async 关键字使编译器创建一个状态机,该状态机管理任务的等待".等待诸如此类的其他功能时,实际上是在创建其中两个不必要的状态机.最好直接从第二个函数返回任务,然后让任务的最终使用者进行等待.

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.

这是一个简单的例子,我只是打了个电话,并使用dotPeek进行了反编译:

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

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

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.

此处是完整的反编译代码: http://pastebin.com/iJLAFdHZ

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

这篇关于我应该对返回任务的每个方法都使用async/await吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆