4

If I made more than one API call at the same time getting error

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 in this context. Any instance members are not guaranteed to be thread-safe.

Exception is thrown from var identity = await base.currentUserService.CreateIdentity(user); as both requests are made at the same time and CreateIdentity method of the previous request is still not finished!

How to solve the above scenario?

I want to wait for IsValidRequest calling in CustomKeyAuthenticationAttribute before the previous request finish.

Here is sample code

public class CustomKeyAuthenticationAttribute : AuthorizeAttribute
{
    [Dependency]
    public IAuthService AuthService { get; set; }

    public override async Task OnAuthorizationAsync(HttpActionContext actionContext, CancellationToken cancellationToken)
    {
         var isValid = await AuthService.IsValidRequest(key-from-request-header);
         if(!isValid){
             return;             
         }
         await base.OnAuthorizationAsync(actionContext, cancellationToken);
    }
}

   // In side AuthService
    public async Task<bool> IsValidRequest(string key)
    {
        if (key-in-db)
        {
            var user = await base.currentUserService.GetUserById(userId-from-request-headers);

            var identity =  await base.currentUserService.CreateIdentity(user);

            var principal = new GenericPrincipal(identity.Result, new string[0]);
            
            HttpContext.Current.User = principal;

            return true;
        }
    return false
 }

  // Inside currentUserService.CreateIdentity method

    public async Task<ClaimsIdentity> CreateIdentity(CustomUser user) {
       return await userManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
    }

Edit

stackTrace: " at System.Data.Entity.Internal.ThrowingMonitor.EnsureNotEntered() at System.Data.Entity.Internal.Linq.InternalSet1.FindAsync(CancellationToken cancellationToken, Object[] keyValues) at System.Data.Entity.DbSet1.FindAsync(CancellationToken cancellationToken, Object[] keyValues) at System.Data.Entity.DbSet1.FindAsync(Object[] keyValues) at Microsoft.AspNet.Identity.EntityFramework.EntityStore1.GetByIdAsync(Object id) at Microsoft.AspNet.Identity.EntityFramework.UserStore6.<GetUserAggregateAsync>d__6c.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.CultureAwaiter1.GetResult() at Microsoft.AspNet.Identity.UserManager2.<GetRolesAsync>d__ac.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.CultureAwaiter1.GetResult() at Microsoft.AspNet.Identity.ClaimsIdentityFactory2.<CreateAsync>d__0.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.TaskAwaiter1.GetResult()

1 Answer 1

1

I would need to see the code behind

var identity =  await base.currentUserService.CreateIdentity(user);

But my guess is that you are setting the DbContext as a shared instance between the various requests. You need to use a different context per thread.

Check this question here for more information as I think it's the same problem.

Another similar problem on entity framwork documentation

Sign up to request clarification or add additional context in comments.

1 Comment

Updated question with CreateIdentity method

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.