Coffee
Coffee

Reputation: 402

EF Core "A second operation started on this context before a previous operation completed" only when deployed

I'm trying to create a web api with very basic authentication for testing.

I create the Context provider like this:

services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")), ServiceLifetime.Transient);

The context class:

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
    {

    }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);
    }

}

I seed some users:

public static void Initialize(IServiceProvider serviceProvider)
    {
        var context = serviceProvider.GetRequiredService<ApplicationDbContext>();
        var userManager = serviceProvider.GetRequiredService<UserManager<ApplicationUser>>();
        context.Database.EnsureCreated();
            ApplicationUser user = new ApplicationUser()
            {
                Email = "[email protected]",
                SecurityStamp = Guid.NewGuid().ToString(),
                UserName = "[email protected]"
            };
            ApplicationUser user2 = new ApplicationUser()
            {
                Email = "[email protected]",
                SecurityStamp = Guid.NewGuid().ToString(),
                UserName = "[email protected]"
            };
        userManager.CreateAsync(user, "Ali@123");
        userManager.CreateAsync(user2, "Ali@123");
    }

Then I use the [Authorize] attribute on my controllers. Now, when I make a call to this api it works 100% in visual studio when debugging, 0 issues at all. However, when deployed to IIS on the same machine i get the error:

System.InvalidOperationException: A second operation started on this context before a previous operation completed. This is usually caused by different threads using the same instance of DbContext. For more information on how to avoid threading issues with DbContext, see https://go.microsoft.com/fwlink/?linkid=2097913.

         at Microsoft.EntityFrameworkCore.Internal.ConcurrencyDetector.EnterCriticalSection()

         at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()

Ive tried almost everything I can think of at this point, the above uses of ApplicationDbContext are the only times it's directly interacted with, so why is it erroring when deployed but working completely fine with the same steps in debugging.

Upvotes: 1

Views: 1340

Answers (1)

Lutti Coelho
Lutti Coelho

Reputation: 2264

The strange part of your question is that it works when you are debugging. This exception means that your context is being used by two threads at the same time, or by two threads in the same request, or by two requests.

The only reason I can think about it does not happen on your machine is that the userManager.CreateAsync(user, "Ali@123"); command finishes its execution before call the next line. (BIG GUESS)

As you are using the CreateAsync method without await it the next line can be executed before the first one finishes its execution. And this behavior rises the exception with the message: “A second operation started on this context before a previous operation completed”

To solve this problem you need to await at least the first CreateAsync call.

    await userManager.CreateAsync(user, "Ali@123");
    userManager.CreateAsync(user2, "Ali@123");

Upvotes: 2

Related Questions