why does the following code always produce an "An asynchronous module or handler completed while an asynchronous operation was still pending"?
When I use 'Dim OriginalUser As ApplicationUser = db.Users.Where(Function(p) p.Id = id).ToList(0)' it works fine.
Lazy Loading is disabled on the ApplicationDBContext which inherits from IdentityDbContext. Why isn't the Context available anymore for the SaveChanges-Part? What am I missing?
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
It's because of Async Sub
. This method should be an asynchronous function returning Task
, and (if you call it yourself) it would need to be called with Await
.
You may find my article on async
on ASP.NET helpful:
When an asynchronous handler completes the request, but ASP.NET detects asynchronous work that hasn’t completed, you get an InvalidOperationException with the message, “An asynchronous module or handler completed while an asynchronous operation was still pending.” This is usually due to asynchronous code calling an async void method
As well as my article on async
best practices:
Avoid async void... Async methods returning void don’t provide an easy way to notify the calling code that they’ve completed. It’s easy to start several async void methods, but it’s not easy to determine when they’ve finished.