[英]How to fire an asynchronous task, but wait for all callbacks before returning ActionResult?
[英]Getting a 404 with asynchronous action (Task<ActionResult>)
很簡單,我已經將一些同步登錄操作轉換為異步,現在找不到它們,獲得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
關鍵字時,它根本不會編譯。 編譯器說從調用View
返回的類型ViewResult
不能隱式轉換為Task<ActionResult>
類型。
現在,如果我使它同步但讓我的HttpPost
回發后登錄驗證方法異步 ,那么當我點擊提交按鈕時MVC路由不會調用它,而是發布到只返回視圖的同步版本!
之前我曾經使用異步操作,我不知道為什么我今天都在掙扎。
當有兩個具有相同名稱/重載的操作方法時,這是一個錯誤嗎?
有誰知道發生了什么?
更新1
好的,所以這很奇怪。
當控制器子類化AsyncController時,它可以工作,但這不應該是它在MVC 4+中的工作方式。
我應該在ASP.NET MVC 4上使用AsyncController嗎?
我正在運行MVC 5,或者應該是。 我還沒有創建一個MVC 3項目......。
我需要做更多的調查並回來。
更新2
我有一個答案,但沒有真正理解為什么。 我嘗試了克里斯關於從動作中刪除Async
后綴的建議並且它有效。
奇怪的是,如上所述,它在使用MVC 3中的“舊” AsyncController
時起作用。
我猜這就是現在的樣子。
異步方法必須要等待 。 否則,它沒有提示何時允許返回其線程,因此將運行同步(在整個時間保持線程)。 警告就是:警告。 它讓你知道你通過使方法異步但不實際做任何異步工作來增加開銷,因此,只是無緣無故地增加開銷。
刪除async
出錯的原因是您仍然返回Task<ActionResult>
。 因此,如果要刪除異步,實際上需要將方法定義更改為:
public ActionResult BetaLoginAsync()
然后,它將編譯沒有錯誤或警告。
顯然,此時命名很尷尬,但是您的兩個方法名稱必須匹配,以允許路由框架回發到同一個URL(沒有屬性路由)。
但是,看到以Async
命名的異步控制器操作實際上是聞所未聞的。
對於其他類型的方法遵循該約定是很常見的,因為它為程序員提供了他們需要等待該方法的線索。 但是,您實際上並不直接調用控制器操作方法,這通常會消除約定的好處。 它還會使傳統路由更加困難,除非您希望Async
顯示在您的URL中(您不應該這樣做)。
所以,我只是從兩種方法中刪除Async
后綴。
克里斯有正確的答案。 當我在ASP.NET MVC 4中編寫使用異步方法時,沒有建立用於命名異步操作方法的約定。 后綴只是約定而與async無關(因為文檔狀態 - “Async”被附加到方法名稱。 附加“Async”不是必需的,但是在編寫異步方法時是慣例.-正如Chris指出的那樣慣例,但不適用於MVC應用程序 )
您的轉換不起作用的原因是您錯過了這一點,並且使用舊的AsyncController工作的原因是舊的AsyncController依賴於異步后綴。 查看源代碼,您可以看到。 另外看一下源代碼,你可以看到AsyncController現在只是一個控制器,因為控制器基類支持async。 為了向后兼容,AsyncController只是留在代碼庫中。
創建一個新的MVC 5應用程序,添加模型,創建一個控制器並檢查異步框。 檢查工作異步代碼,這可能會幫助你弄清楚你做錯了什么。 異步MVC非常常見並且被廣泛使用。
也許MVC不匹配具有相同名稱的同步和異步操作。
也就是說, BetaLoginAsync()
很好。 沒有異步工作要做。 這是該警告的假陽性案例。
你可以使用return Task.FromResult(View());
如果你喜歡。 沒關系。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.