很简单,我已经将一些同步登录操作转换为异步,现在找不到它们,获得404.
public async Task<ActionResult> BetaLoginAsync()
{
return View();
}
[HttpPost]
public async Task<ActionResult> BetaLoginAsync(Models.Authentication.SimpleLoginModel loginModel, string returnUrl)
{
if (this.ModelState.IsValid)
{
if (await this.ValidateCredentialsAsync(loginModel))
{
...
我以为我已经完成了所有需要,我跟着这个:
http://www.asp.net/mvc/tutorials/mvc-4/using-asynchronous-methods-in-aspnet-mvc-4
编译器警告我,仅返回视图的第一个操作方法不使用await
关键字,因此它将同步运行。
问题在于,当我删除async
关键字时,它根本就不会编译。编译器说,从ViewResult
调用返回的类型View
无法隐式转换为Task<ActionResult>
类型。
现在,如果我将它同步但保留我的HttpPost
回发后登录验证方法异步,那么单击提交按钮时MVC路由不会调用它,而是发布到只返回视图的同步版本!!
之前我曾经使用异步操作,我不知道为什么我今天在挣扎。
当有两个具有相同名称/重载的操作方法时,这是一个错误吗?
有谁知道发生了什么事?
更新1
好的,这很奇怪。
当控制器子类化AsyncController时,它可以工作,但这不应该是它在MVC 4 +中的工作方式。
我应该在ASP.NET MVC 4上使用AsyncController吗?
我正在运行MVC 5,或者应该是。我还没有创建一个MVC 3项目......。
我需要做更多的调查并回来。
更新2
我有一个答案,但没有真正理解为什么。我尝试了克里斯关于从行动中删除Async
后缀的建议,并且它有效。
奇怪的是,如上所述,它在使用MVC 3中的“旧”AsyncController
时有效。
我想这就是它现在的样子。
答案 0 :(得分:4)
异步方法必须具有等待的功能。否则,它没有提示何时允许返回其线程,因此将运行同步(在整个时间保持线程)。警告就是:警告。它让你知道你通过使方法异步但不实际做任何异步工作来增加开销,因此,只是无缘无故地增加开销。
删除async
时出错的原因是您仍然返回Task<ActionResult>
。因此,如果要删除异步,实际上需要将方法定义更改为:
public ActionResult BetaLoginAsync()
然后,它将编译而不会出现错误或警告。
显然,此时命名很尴尬,但是你的两个方法名必须匹配,以允许路由框架回发到同一个URL(没有属性路由)。
然而,看到以Async
命名的异步控制器操作实际上是闻所未闻的。
对于其他类型的方法遵循该约定是很常见的,因为它为程序员提供了他们需要等待该方法的线索。但是,您实际上并不直接调用控制器操作方法,这通常会消除约定的好处。除非您希望Async
显示在您的网址中(您不应该这样做),否则它还会使传统路由变得更加困难。
所以,我只想从两种方法中删除Async
后缀。
答案 1 :(得分:3)
您的转换无法正常工作的原因是您错过了这一点,并且使用旧的AsyncController工作的原因是旧的AsyncController依赖于异步后缀。查看源代码,您可以看到。另外看一下源代码,你可以看到AsyncController现在只是一个控制器,因为控制器基类支持async。 AsyncController刚刚留在代码库中以实现向后兼容。
创建一个新的MVC 5应用程序,添加模型,创建一个控制器并检查异步框。检查工作异步代码,这可能会帮助您弄清楚您做错了什么。异步MVC非常常见并且被广泛使用。
答案 2 :(得分:1)
也许MVC没有匹配同名和异步动作同名。
那就是说,BetaLoginAsync()
现在很好。没有异步工作要做。这是警告的假阳性案例。
如果您愿意,可以使用return Task.FromResult(View());
。这没关系。