I have what seems like a relatively simple HTTP GET request to acquire the number of user notifications a specific user has. The problem occurs about 50% of the time. The request is done through an AJAX call on the client every 10 seconds or so. Similar problems (though not as frequent) have occurred in other areas of the application when UserManager is performing awaitable calls.
I have tried to be sure that other async operations are not occurring by gutting the code in this path to the bare essentials.
[Authorize]
public class NotificationsApiController : ApiController
{
[Route("api/NotificationsApi/GetNotificationsCount/")]
public async System.Threading.Tasks.Task<string> GetUserIdAsync()
{
string userId = null;
string username = HttpContext.Current.User.Identity.Name;
ApplicationUserManager um = HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>();
var currentUser = await um.FindByNameAsync(username);
userId = currentUser.Id;
return userId;
}
}
I often get this exception when running, but only sometimes (I have cut the output down to the offending line):
System.NotSupportedException
A second operation started on this context before a previous asynchronous operation completed. Use 'await' to ensure that any asynchronous operations have completed before calling another method on this context. Any instance members are not guaranteed to be thread safe.
at System.Data.Entity.Internal.ThrowingMonitor.EnsureNotEntered()
at System.Data.Entity.Core.Objects.ObjectQuery`1.System.Data.Entity.Infrastructure.IDbAsyncEnumerable<T>.GetAsyncEnumerator()
at System.Data.Entity.Infrastructure.IDbAsyncEnumerableExtensions.<FirstOrDefaultAsync>d__25`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNet.Identity.TaskExtensions.CultureAwaiter`1.GetResult()
at Microsoft.AspNet.Identity.EntityFramework.UserStore`6.<GetUserAggregateAsync>d__67.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at CORT.Controllers.NotificationsApiController.<GetUserIdAsync>d__0.MoveNext() in Controllers\WebAPIs\NotificationsApiController.cs:line 24
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Threading.Tasks.TaskHelpersExtensions.<CastToObject>d__1`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Filters.AuthorizationFilterAttribute.<ExecuteAuthorizationFilterAsyncCore>d__3.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__15.MoveNext()"}
This line is shown above: var currentUser = await um.FindByNameAsync(username);
EDIT: I changed the original notification code presented in the question because it was confusing users. The code above is now the entire class involved in the problem. It focuses on the simple task of returning the user id. It is not a real part of my application (though this is what I am running), but the problem occurring simplifies to this example. Let me know if there are other sections of the code that may be helpful to post.