Asp.net core: Cannot access a disposed object. A common cause of this error is disposing a context that was resolved from dependency injection

I am developing a web api project. Nowadays, I have a problem when calling an endpoint. I do not constantly get an error when calling this endpoint, for example if I am calling 30 times a day, I get this error 2 times. This endpoint just select the data and working async. I tried all the solutions I found on the internet but it didn't work. Error: Cannot access a disposed object. A common cause of this error is disposing a context that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur if you are calling Dispose() on the context, or wrapping the context in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances.

 public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<MyContext>(options => options.UseMySql(Environment.GetEnvironmentVariable("MY_DB_CONNECTION")), ServiceLifetime.Transient);
services.DIRegisterer();
}

public static IServiceCollection DIRegisterer(this IServiceCollection services)
{
services.AddScoped<MyService>();
}

Note: I'm using .net core 3.1

1 answer

  • answered 2021-03-08 19:48 Steven

    As this problem only shows sporadically, a likely cause of the problem is an (accidental) spawn background operation running parallel to the request operation. This parallel operation has access to the request's DbContext instance.

    NOTE: In case the error would persist after an initial successful operation, this would be an indication that the DbContext is held captive by one of its consumers; in other words, a Captive Dependency.

    In most cases the background operation finishes before the request ends, and thus before the DbContext is disposed of. In some cases, however, there is a delay in that (accidental) parallel operation, causing it to access the DbContext after the request has ended, and thus after the DbContext was disposed of by ASP.NET Core.

    This might have happened because you forgot to await an asynchronous operation. When you forget to await such operation, it starts running in parallel. Running such code in parallel, however, is often problematic, especially when dealing with objects such as DbContext, as they are not thread-safe.

    So analyze the stack trace to find the place where you forgot to await the operation. For instance:

    public async Task DoSomethingAsync()
    {
         await this.DoSomethingNiceAsync();
         this.DoSomethingElseAsync(); // forgot to await
    }
    
    private async Task DoSomethingElseAsync()
    {
        // Makes use of dbcontext
        await this.dbContext.GetEntitiesAsync();
    }