【问题标题】:Always using Async in an ASP.NET MVC Controller始终在 ASP.NET MVC 控制器中使用异步
【发布时间】:2014-12-13 15:40:22
【问题描述】:
我最近继承了一个 ASP.NET MVC 项目。在那个项目中,开发者使用async everywhere。我正在尝试评估它是否是一个好主意。具体来说,我现在正在查看控制器代码。
在控制器中,开发人员编写了如下内容:
public async Task<ActionResult> Index()
{
return View();
}
这个比传统版本有什么优势吗:
public ActionResult Index()
{
return View();
}
如果在控制器代码中使用了await,我可以理解使用async。很多时候,它虽然没有被使用。这种方法有什么理由吗?
【问题讨论】:
-
我这个这个article 总结了 AsyncController 的用途。
标签:
c#
asp.net-mvc
asynchronous
【解决方案1】:
没有。在任何地方都使用 Async 并不是一个好主意。
关于缺少的 await,当 Async 方法不包含 Await 运算符时,编译器会发出警告。没有 await 的 Async 方法将同步运行,这使得语义不正确。
对于您的具体示例,操作简单且运行时间短,这就是为什么使用 Async/Await 不会带来任何好处,也不应该使用它,因此您完全可以使用:
public ActionResult Index()
{
return View();
}
Async/Await 应该用于执行某种 IO 的控制器方法(例如网络请求、数据库访问等)。如果控制器方法正在执行 CPU 密集型工作(例如数学计算),那么使用 Async/Await 实际上会使性能变差,除非您的测量结果证明我错了。
适用旧规则:测量两次,切割一次。
【解决方案2】:
如果此方法中的任何地方都没有await,则执行操作/方法是没有意义的。制作方法async 意味着“在盒子下”(由编译器)将创建状态机,这与纯 void 版本相比会产生一点开销(开销确实很小,但如果你每秒有数百万个请求可以产生影响;)) .如果你害怕很快就会引入 await (你最好有充分的理由“害怕”)并且你有很多代码依赖于这个方法(例如它是抽象类方法/它属于接口)你应该保留方法返回 Task<ActionResult> 但没有将其标记为异步。示例:
public Task<ActionResult> MyAction() {
return Task.FromResult<ActionResult>(View());
}
此Task.FromResult<T> 方法返回已完成的任务 - 这可防止编译器创建异步状态机。
回到您的主要问题 - 编写此代码的人似乎不知道他们在做什么 - 标记方法异步并不意味着该方法“异步”工作。