Ahmed el-shiekh
Ahmed el-shiekh

Reputation: 3

InvalidOperationException: different threads concurrently using the same instance of DbContext

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 am using ASP.NET Core 7.

I have a Users Controller to manage Identity Users as follows:

namespace Aqbel.Controllers;

public class UsersController : Controller
{
    private readonly UserManager<ApplicationUser> _userManager;
    private readonly RoleManager<IdentityRole> _roleManager;

    public UsersController(UserManager<ApplicationUser> userManager,
        RoleManager<IdentityRole> roleManager)
    {
        _userManager = userManager;
        _roleManager = roleManager;
    }

    public async Task<IActionResult> Index()
    {
        var users = await _userManager.Users.Select(user => new UserViewModel
        {
            Id = user.Id,
            FirstName = user.FirstName,
            LastName = user.LastName,
            UserName = user.UserName,
            Email = user.Email,
            Roles = _userManager.GetRolesAsync(user).Result
        }).ToListAsync();
        return View(users);
    }
}

Index View as follows

@model IEnumerable<UserViewModel>

@{ ViewData["Title"] = "Users"; }

<h1>@ViewData["Title"]</h1>
<a asp-action="Add" class="btn btn-primary">Add User</a>

<table class="table table-striped mt-4">
    <thead>
        <tr>
            <th>Name</th>
            <th>LastName</th>
            <th>Username</th>
            <th> Email</th>
            <th>Roles</th>
            <th>Manage Roles</th>
        </tr>
    </thead>

    <tbody>
        @foreach (var user in Model)
        {
            <tr>
                <td>@user.FirstName</td>
                <td>@user.LastName</td>
                <td>@user.UserName</td>
                <td>@user.Email</td>
                <td>@string.Join(" , ", user.Roles.ToList())</td>
                <td>
                    <a class="btn btn-primary" asp-action="ManageRoles" asp-route- userId="@user.Id">Roles</a>
                    <a class="btn btn-outline-secondary" asp-action="Edit" asp-route-userId="@user.Id">Edit</a>
                </td>
            </tr>
        }
    </tbody>
</table>

Is there anything wrong in the codes to get this type of error?

Upvotes: 0

Views: 476

Answers (1)

Jason Pan
Jason Pan

Reputation: 22082

You're using .Result on a Task, which is a blocking call.

Roles = _userManager.GetRolesAsync(user).Result <--- problem here

We can change Index method like below to fix the issue.

public async Task<IActionResult> Index()
{
    var users = await _userManager.Users.ToListAsync();
    
    var userViewModels = new List<UserViewModel>();

    foreach (var user in users)
    {
        var roles = await _userManager.GetRolesAsync(user);
        userViewModels.Add(new UserViewModel
        {
            Id = user.Id,
            FirstName = user.FirstName,
            LastName = user.LastName,
            UserName = user.UserName,
            Email = user.Email,
            Roles = roles
        });
    }

    return View(userViewModels);
}

Upvotes: 0

Related Questions