MudBlazor与ASP.NET Core UserManager并行执行DbContext跟踪冲突问题
问题:MudBlazor与ASP.NET Core UserManager并行加载时的DbContext跟踪冲突
场景复现
- 应用右上角设有个人资料下拉菜单,点击“编辑资料”跳转至对应页面时,两个组件会同时加载
- 刷新页面时,MudBlazor会并行加载这两个组件,两者均在
OnInitializedAsync方法内通过ASP.NET Core的UserManager获取当前用户
核心问题
两个UserManager请求复用了同一个DbContext,导致抛出ApplicationUser实例已被跟踪的错误。疑惑:UserManager作为作用域服务,默认情况下难道不具备线程安全性吗?
已实现的解决方案
通过自定义UserService结合TaskCompletionSource处理并行请求,确保只执行一次用户查询,代码如下:
public class UserService(SignInManager<ApplicationUser> signInManager, IHttpContextAccessor httpContextAccessor) : IUserService { public SignInManager<ApplicationUser> SignInManager { get; } = signInManager; private readonly TaskCompletionSource<ApplicationUser?> _taskCompletionSource = new(); private int _isInitialized = 0; public async Task<ApplicationUser?> GetUserAsync(ClaimsPrincipal claimsPrincipal) { if (Interlocked.CompareExchange(ref _isInitialized, 1, 0) == 0) { var user = await SignInManager.UserManager.GetUserAsync(claimsPrincipal); _taskCompletionSource.SetResult(user); return user; } return await _taskCompletionSource.Task; } public async Task<ApplicationUser?> GetUserAsync() { var user = httpContextAccessor.HttpContext?.User; if (user != null) { return await GetUserAsync(user); } return null; } }
在Program.cs中的注册方式:
services.AddScoped<IUserService, UserService>();
希望了解是否存在官方或更简洁的默认线程安全实现方式。
内容的提问来源于stack exchange,提问作者CrazyEight
相关产品推荐
相关产品推荐

