6 Replies - 242 Views - Last Post: 12 August 2019 - 09:46 AM Rate Topic: -----

#1 macadameane   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 4
  • Joined: 12-August 19

Where else is this context being used?

Posted 12 August 2019 - 07:32 AM

I have what seems like a relatively simple HTTP API 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.

[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;
    }
}



When the problem occurs, I get the following exception/stack trace:

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()"}



I've looked around quite a bit searching for an answer, but have come up short. If there is any other code I can post to assist, please let me know. Thanks.

Is This A Good Question/Topic? 0
  • +

Replies To: Where else is this context being used?

#2 modi123_1   User is online

  • Suitor #2
  • member icon



Reputation: 15170
  • View blog
  • Posts: 60,713
  • Joined: 12-June 08

Re: Where else is this context being used?

Posted 12 August 2019 - 08:26 AM

Can you slap a try/catch in there and log more precise exceptions?

If that specific function is being called have you considered caching or slapping the value in session to ease up on it tripping on itself?
Was This Post Helpful? 0
  • +
  • -

#3 macadameane   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 4
  • Joined: 12-August 19

Re: Where else is this context being used?

Posted 12 August 2019 - 09:00 AM

View Postmodi123_1, on 12 August 2019 - 08:26 AM, said:

Can you slap a try/catch in there and log more precise exceptions?

If that specific function is being called have you considered caching or slapping the value in session to ease up on it tripping on itself?


The provided stack trace was obtained with a try catch. To be more clear, the original code was getting the user's id and getting a count of that users notifications. I cut all the other code out to find the cause of the issue. While I could store/cache the users id some other way, I would like to fix the underlying problem. From other examples I've seen, this should be an acceptable way to safely get this information.

What other information were you hoping that I could gather from the try catch that is missing?

Thanks for the response.
Was This Post Helpful? 0
  • +
  • -

#4 modi123_1   User is online

  • Suitor #2
  • member icon



Reputation: 15170
  • View blog
  • Posts: 60,713
  • Joined: 12-June 08

Re: Where else is this context being used?

Posted 12 August 2019 - 09:24 AM

*shrug* Something more specific, but not even sure about that without having the entire chunk of code for that function.
Was This Post Helpful? 0
  • +
  • -

#5 macadameane   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 4
  • Joined: 12-August 19

Re: Where else is this context being used?

Posted 12 August 2019 - 09:27 AM

View Postmodi123_1, on 12 August 2019 - 09:24 AM, said:

*shrug* Something more specific, but not even sure about that without having the entire chunk of code for that function.


This is the entire chunk of code as it is running now.
Was This Post Helpful? 0
  • +
  • -

#6 modi123_1   User is online

  • Suitor #2
  • member icon



Reputation: 15170
  • View blog
  • Posts: 60,713
  • Joined: 12-June 08

Re: Where else is this context being used?

Posted 12 August 2019 - 09:33 AM

Quote

To be more clear, the original code was getting the user's id and getting a count of that users notifications. I cut all the other code out to find the cause of the issue.


I guess so it goes.

I would verify the ajax call is async, and if need be put that function's guts in an async call block. Track back to any EF context and make sure that all has await in it.
Was This Post Helpful? 0
  • +
  • -

#7 macadameane   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 4
  • Joined: 12-August 19

Re: Where else is this context being used?

Posted 12 August 2019 - 09:46 AM

I actually constructed a view that is bare bones and makes no other calls on the application. The only thing happening is an asynchronous AJAX call using jQuery ($.get to be specific) every 10 seconds. The calls execute quickly and returns quickly whether from an error in this case, or the user id string returns. The only context at play here is perhaps the ApplicationDbContext which is derived from IdentityDbContext<ApplicationUser> and the OwinContext. I haven't been able to find other places where await isn't being used, except where I am setting up the application and the setup functions are wanting tasks returned (it appears).
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1