始终在 ASP.NET MVC 控制器中使用异步

本文关键字:异步 控制器 MVC ASP NET | 更新日期: 2023-09-27 18:34:06

我最近继承了一个 ASP.NET 的MVC项目。在该项目中,开发人员在任何地方都使用async。我正在尝试评估这是否是一个好主意。 具体来说,我目前正在审查控制器代码。

在控制器中,开发人员编写了如下内容:

public async Task<ActionResult> Index()
{
  return View();
}

这比传统版本有什么好处吗:

public ActionResult Index()
{
  return View();
}

如果控制器代码中使用了await,我可以理解使用 async。很多时候,它没有被使用。这种做法有什么道理吗?

始终在 ASP.NET MVC 控制器中使用异步

No.在任何地方都使用异步不是一个好主意。

关于缺少的等待,编译器会在Async方法不包含Await运算符时发出警告。没有 await 的异步方法将同步运行,这使得语义不正确。

对于您的特定示例,该操作简单且运行时间短,这就是为什么使用 Async/Await 不会带来任何好处,也不应该使用它,因此您可以使用:

public ActionResult Index()
{
    return View();
}

Async/Await 应该用于执行某种 IO(例如网络请求、数据库访问等)的控制器方法。如果控制器方法正在执行 CPU 密集型工作(例如数学计算),那么使用 Async/Await 实际上会使性能变差,除非您的测量证明我错了。

旧规则适用:测量两次,切割一次

如果此方法中任何地方都没有await,则进行操作/方法就没有意义。制作方法async意味着"在盒子下"(通过编译器)将创建状态机,与纯 void 版本相比,它会产生一点开销(开销真的很小,但如果你每秒有百万个请求,这可能会在;)产生影响)。如果你害怕很快就会引入 await(你最好有充分的理由"害怕"),并且你有很多代码依赖于这种方法(例如它是抽象类方法/它属于接口),你应该保持方法返回Task<ActionResult>但不将其标记为异步。例:

public Task<ActionResult> MyAction() {
    return Task.FromResult<ActionResult>(View());
}

Task.FromResult<T>方法返回已完成的任务 - 这会阻止编译器创建异步状态机。

回到你的主要问题 - 似乎编写此代码的人不知道他们在做什么 - 标记方法异步并不意味着该方法"异步"工作。