0

I know that this problem is here a lot, but I have to say I read everything I could found for like two days and don't get my error.

I created a ASP.net Core REST API and get always different errors:

  • "Can not access a disposed object.."
  • "An exception occurred while iterating over the results of a query for context type.."
  • "A second operation started on this context before a previous operation completed"..

Maybe someone of you sees my error or can explain to me, what I'm doing wrong.

Rest-API:

 // POST api/events
    [HttpPost("create")]
    public async Task<IActionResult> CreateAsync([FromBody] EventDTO eventDTO)
    {
        var newEvent = _mapper.Map<Event>(eventDTO);
        try
        {
            await _eventService.CreateEventAsync(newEvent);

            return Ok(newEvent);
        }
        catch (AppException ex)
        {
            return BadRequest(new { message = ex.Message });
        }
    }

Interface:

public interface IEventService
{
    Task<IEnumerable<Event>> GetAllEventsAsync();
    Task<Event> GetEventByIDAsync(int id);
    Task<IEnumerable<Event>> GetEventByCityAsync(string city);
    Task<Event> CreateEventAsync(Event newEvent);
    void UpdateEventAsync(Event newEvent, Event existing, int eventId);
    void DeleteEventAsync(Event existing);
}

Eventservice:

 public class EventService : IEventService
{
    private MeMeContext _dbContext;

    public EventService(MeMeContext dbContext)
    {
        _dbContext = dbContext;
    } 

    public async Task<Event> CreateEventAsync(Event newEvent)
    {
        _dbContext.Events.Add(newEvent);
        await _dbContext.SaveChangesAsync();
        return newEvent;
    }
    ...
}

Startup:

        public void ConfigureServices(IServiceCollection services)
    {
        services.AddCors();
        services.AddMvc().
            SetCompatibilityVersion(CompatibilityVersion.Version_2_2).
            AddJsonOptions(opts => opts.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore);

        services.AddDbContext<MeMeContext>(opts => opts.UseNpgsql(Configuration.GetConnectionString(DATABASE)));
        services.AddScoped<MeMeContext>();
        // configure DI for application services
        services.AddScoped<IUserService, UserService>();
        services.AddScoped<IEventService, EventService>();

        var mappingConfig = new MapperConfiguration(mc =>
        {
            mc.AddProfile(new AutoMapperProfile());
        });

        IMapper mapper = mappingConfig.CreateMapper();
        services.AddSingleton(mapper);
    ...
}

One thing that I don't understand also, is that I get different errors, when I start my application with Visual Studio or with "dotnet run". One thing that also happens from time to time is, that sometimes my code works, when I do other things on the REST API.

When you need more information, just ask. I'm happy with every hint that you can give me :) Thanks in advance!

2
  • Which line is producing the errors? Commented Sep 17, 2019 at 16:50
  • @TKK it is produced at line "await _dbContext.SaveChangesAsync();" Commented Sep 17, 2019 at 17:42

1 Answer 1

2

You're not awaiting an async method. As such, the code in the action moves on while that CreateEventAsync logic is running. When the response returns, the context goes away, since its lifetime is that scope.

In other words, you have essentially a race condition. If the CreateEventAsync logic happens to finish before the response returns, everything is fine. However, if it takes longer than returning the response, then the context is gone (along with your other scoped services), and you start throwing exceptions.

Long and short, use the await keyword:

await _eventService.CreateEventAsync(newEvent);

Async is not the same as running something in the background. If you want the action to be able to return before this logic completes, then you should schedule this to run on a background service instead. See: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-2.2&tabs=visual-studio

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

5 Comments

I added your idea (after I felt really stupid), but I get the third error again. ( A second operation startet on this context...)
You probably have another instance of not awaiting somewhere.
Jip you are right.. oh man is this frustrating.. but thank you VERY MUCH!
Two things can help. First, name any async method you create with Async at the end. Then, for any method that has Async at the end you should add await before it. There's exceptions, but it's far more common that you need the await than you don't, and when you don't, there should be a good reason that you are fully aware of.
I think I need to read some things about the await/async thing, to fully understand it.

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.