我是否需要在 Visual Studio 2017 ASP.NET Core MVC 中将异步添加到我的控制器操作

Do I need to add Async to my Controller Actions in Visual Studio 2017 ASP.NET Core MVC

我刚刚将我的 Visual Studio 2015 ASP.NET MVC Core 项目转换为 Visual Studio 2017...我在我的错误列表中收到以下信息性消息

消息 IDE1006 违反命名规则:缺少后缀:'Async'

此消息出现在我的控制器中,主要关注以下内容:

public async Task<IActionResult> Index()

这也适用于创建、删除、详细信息和编辑。这些消息显示为信息性消息,适用于我项目中的 1,000 多次出现。看来我需要将 Index 更改为 IndexAsync 即
更改自:

public async Task<IActionResult> Index()
public async Task<IActionResult> Create()
public async Task<IActionResult> Delete(int? id)
public async Task<IActionResult> Details(int? id)

更改为:

public async Task<IActionResult> IndexAsync()
public async Task<IActionResult> CreateAsync()
public async Task<IActionResult> DeleteAsync(int? id)
public async Task<IActionResult> DetailsAysnc(int? id)

此时这似乎是可选的,因为我的项目将构建并且这在 VS 2015 中不是问题。我不介意做这项工作,我需要确认在 Visual Studio 2017 ASP.NET核心才是正确的做法。

Microsoft 正在推动您为异步方法添加 async 后缀。为什么? Visual Studio 2017 年的 release notes 提到了这个花絮。

Task-like return types for async methods: This introduces the ability to return any task-like type from an async method. Previously these return types were constrained to Task<T> and Task.

听起来似乎仅通过检查它们的 return 类型就会变得不那么明显哪些方法是异步的。给它们加上 async 后缀可能是个好主意。在 VS 制作这个 "suggestion" 之前,有一个 previous stack overflow question 讨论这个约定。 Microsoft 的 Stephen Toub 解决了这个问题,我引用了它。

If a public method is Task-returning and is asynchronous in nature (as opposed to a method that is known to always execute synchronously to completion but still returns a Task for some reason), it should have an “Async” suffix. That’s the guideline. The primary goal here with the naming is to make it very obvious to a consumer of the functionality that the method being invoked will likely not complete all of its work synchronously; it of course also helps with the case where functionality is exposed with both synchronous and asynchronous methods such that you need a name difference to distinguish them. How the method achieves its asynchronous implementation is immaterial to the naming: whether async/await is used to garner the compiler’s help, or whether types and methods from System.Threading.Tasks are used directly (e.g. TaskCompletionSource) doesn’t really matter, as that doesn’t affect the method’s signature as far as a consumer of the method is concerned.

Of course, there are always exceptions to a guideline. The most notable one in the case of naming would be cases where an entire type’s raison d’etre is to provide async-focused functionality, in which case having Async on every method would be overkill, e.g. the methods on Task itself that produce other Tasks.

As for void-returning asynchronous methods, it’s not desirable to have those in public surface area, since the caller has no good way of knowing when the asynchronous work has completed. If you must expose a void-returning asynchronous method publicly, though, you likely do want to have a name that conveys that asynchronous work is being initiated, and you could use the “Async” suffix here if it made sense. Given how rare this case should be, I’d argue it’s really a case-by-case kind of decision.

I hope that helps, Steve

底线是信息性的。但随着 Microsoft 将 return 类型扩展到 Task 之外,它开始看起来越来越像最佳实践。使用你自己的判断。

我注意到对于 MVC 控制器 类,除了向方法名称添加 Async 之外,我还需要添加 [ActionName("MethodName")] 作为方法属性,其中 "MethodName" 最后没有异步。如果我没有添加 ActionName 属性,代码会编译,但 URL 不会路由到该方法,除非我也在 URL 中添加 Async。我不想在我的 URL 中使用 Async,所以我最终在所有地方都添加了 ActionName 属性。看起来 MVC 路由引擎应该尝试找到 Async 方法,但事实并非如此。