Search code examples
c#asp.net-core.net-core.net-8.0

InvalidOperationException: a second operation was started on this context instance before a previous operation completed


I'm working on an application on .NET Core 8 which uses EF and authentication with individual accounts. I'm trying to display a set of users with their roles. I got the code from this page:

The page I got the code from

This is that code:

public IActionResult Index()
{
    var users = _userManager.Users.Select(c => new UsersViewModel()
    {
        Username = c.UserName,
        Email = c.Email,
        Role = string.Join(",", _userManager.GetRolesAsync(c).Result.ToArray())
    }).ToList();

    return View(users);
}

To work with my application I have modified the code to:

public IList<User> Users { get; set; } = default!;

public async Task OnGetAsync()
{
    IQueryable<User> users = _userManager.Users.Select(c => new User()
    {
        Username = c.UserName,
        Role = string.Join(",", _userManager.GetRolesAsync(c).Result.ToArray())
    });

    Users = await users.ToListAsync();
}

When I run this application, sometimes I get the following error:

An unhandled exception occurred while processing the request.
InvalidOperationException: A second operation was started on this context instance before a previous operation completed. This is usually caused by different threads concurrently 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.

I assumed that it's caused by the GetRolesAsync method not having an await. And I added an await like this:

IQueryable<User> users = _userManager.Users.Select(c => new User()
{
    Username = c.UserName,
    Role = string.Join(",", await _userManager.GetRolesAsync(c).Result.ToArray())
});

Users = await users.ToListAsync();

Then I get the compile-time error:

'string[]' doesn't contain a definition for 'GetAwaiter' and no accessible extension method 'GetAwaiter' accepting a first argument of type 'string[]' could be found

Can someone explain to me how to correct this code? I tried a few other changes also but all of them have various compiler errors.


Solution

  • You could try following code which works.

            public async Task OnGetAsync()
            {
                var users = new List<User>();
    
                var items = await _userManager.Users.ToListAsync();
                foreach (var c in items)
                {
    
                    var result = await _userManager.GetRolesAsync(c);
                    users.Add(new User()
                    {
                        Username = c.UserName,
                        Role = string.Join(",", result.ToArray())
                    });
                }
                var final = users;
            }
    

    Test
    enter image description here