Search code examples
c#asp.net-coreasync-awaitasp.net-identity

Dependency Injected UserManager is disposing on async call (ASP.NET CORE)


I am using ASP.NET Core with its inbuilt dependency injection and asp.net identity.

The problem I am having is whenever I try and access any of the context's via async (ie in this example UserManager<ApplicationUser>) it is being disposed when accessing.

For example, my controller is below (The object we are concerned with is UserManager)

private readonly ApplicationDbContext _dbContext;
private readonly UserManager<ApplicationUser> _userManager;
private readonly ViewRender _view;
private readonly IConfiguration _config;

public UserController(ApplicationDbContext dbContext,
    UserManager<ApplicationUser> userManager,
    ViewRender view,
    IConfiguration config)
{
    this._dbContext = dbContext;
    this._userManager = userManager;
    this._view = view;
    this._config = config;
}

Notice the _userManager is being injected using the visual studio template default setting in startup.cs

Now in a method in this controller I try the following:

[HttpDelete]
public async void Delete(string id)
{

    var user = _userManager.Users.Where(a => a.Id == id).FirstOrDefault();
    user.Deleted = true;
    var result= await _userManager.UpdateAsync(user);

}

but when the await _userManager.UpdateAsync(user) is hit, it calls a "the object is disposed" error. My understanding of async / await is that the execution will stop at await? Therefore the controller should not dispose _userManager object until its completed? (obviously this logic is wrong)

A solution which works is to not use a aysnc method and just call _userManager.UpdateAsync(user).Result; but would like to understand aysnc/await


Solution

  • Update action to have Task return type instead of void:

    [HttpDelete]
    public async Task Delete(string id) {
        var user = _userManager.Users.Where(a => a.Id == id).FirstOrDefault();
        user.Deleted = true;
        var result= await _userManager.UpdateAsync(user);
    }
    

    For a better understanding of async/await read this article

    Async/Await - Best Practices in Asynchronous Programming