0

爲什麼下面的代碼總是產生「異步模塊或處理程序在異步操作仍未完成時完成」?使用異步時EF IdentityDbContext出現問題方法

當我使用'Dim OriginalUser As ApplicationUser = db.Users.Where(Function(p)p.Id = id).ToList(0)'它工作正常。

延遲加載在從IdentityDbContext繼承的ApplicationDBContext上被禁用。爲什麼SaveChanges-Part沒有可用的上下文?我錯過了什麼?

Public Async Sub PatchUser(id As String, <FromBody> ChangedUserAttributes As Delta(Of ApplicationUser)) 
    Using ctx As New ApplicationDbContext 
     Validate(ChangedUserAttributes.GetEntity()) 

     If Not ModelState.IsValid Then 
      Throw New HttpResponseException(New HttpResponseMessage(HttpStatusCode.BadRequest)) 
     End If 

     Dim OriginalUser As ApplicationUser = Await ctx.Users.SingleOrDefaultAsync(Function(p) p.Id = id) 
     If OriginalUser Is Nothing Then 
      Throw New HttpResponseException(HttpStatusCode.NotFound) 
     End If 

     Try 
      ChangedUserAttributes.TrySetPropertyValue("Email", "Emil") 
      ChangedUserAttributes.Patch(OriginalUser) 
      Await ctx.SaveChangesAsync 
      Return 
     Catch ex As Exception 
      Throw New HttpResponseException(New HttpResponseMessage(HttpStatusCode.BadRequest)) 
     End Try 
    End Using 
End Sub 

回答

3

這是因爲Async Sub。該方法應該是一個返回Task的異步函數,並且(如果您自己調用它),則需要使用Await調用該方法。

您可能會發現我的文章async on ASP.NET helpful

當異步處理程序完成的請求,但ASP.NET檢測尚未完成異步工作,你會得到一個InvalidOperationException與消息,「異步模塊或處理程序,而異步操作仍有待完成「這通常是由於異步代碼調用一個異步方法無效

,以及我的文章async best practices

避免異步無效...返回void的異步方法不提供簡單的方法來通知調用代碼,他們已完成。啓動幾個異步無效方法很容易,但確定何時完成並不容易。

+0

它看起來像是一個控制器動作,所以它不會被直接調用,但是對於「Async Function ... As Task」而不是「Async Sub」你當然是正確的。 – jmcilhinney

+0

謝謝,這已經有所幫助。我使用了一個Sub,因爲在WEB API的PATCH動作中,根據Microsoft的結果應該是204(無內容)(https://www.asp.net/web-api/overview/getting-started-with-aspnet-網上API /行動結果)。但是當我嘗試返回返回新的HttpResponseMessage(HttpStatusCode.NoContent)時,我得到一個'無法轉換'System.Net.Http.HttpResponseMessage'類型的對象來鍵入'System.Web.Http.IHttpActionResult'錯誤。 – user3767106

+0

@ user3767106:你應該只返回一個普通的'Task',而不是*任務*。 –