Blazor Server中UserManager.CreateAsync出现已释放对象访问异常
问题分析与解决方案
根源排查
Blazor Server中出现UserManager已释放的异常,核心原因是Scoped服务生命周期与组件/电路的绑定关系:
UserManager<TUser>默认注册为Scoped服务,其生命周期与当前电路(Circuit)绑定。当用户断开连接、组件被销毁(如导航离开),或电路重连后,旧的Scoped实例会被自动释放。- 若组件在实例释放后仍持有引用并调用其方法(比如未完成的异步操作延迟执行),就会触发
ObjectDisposedException。
解决方案
1. 检查组件状态再执行操作
在异步方法开头判断组件是否已被销毁,避免访问已释放的服务:
async Task<bool> CreateLoginUser() { // 组件已销毁则直接返回 if (IsDisposed) return false; var user = new CustomUser { UserName = SelectedPerson.Email, Email = SelectedPerson.Email }; var result = await usrm.CreateAsync(user, UserPassword); return result.Succeeded; }
2. 临时Scope获取服务实例
通过IServiceScopeFactory创建临时Scope,确保每次操作都获取当前有效的UserManager实例:
@inject IServiceScopeFactory ScopeFactory async Task<bool> CreateLoginUser() { using var scope = ScopeFactory.CreateScope(); var usrm = scope.ServiceProvider.GetRequiredService<UserManager<CustomUser>>(); var user = new CustomUser { UserName = SelectedPerson.Email, Email = SelectedPerson.Email }; var result = await usrm.CreateAsync(user, UserPassword); return result.Succeeded; }
3. 取消组件销毁后的异步操作
使用CancellationTokenSource在组件销毁时取消未完成的异步操作,避免后续访问已释放的服务:
private CancellationTokenSource _operationCts = new(); async Task<bool> CreateLoginUser() { try { var user = new CustomUser { UserName = SelectedPerson.Email, Email = SelectedPerson.Email }; var result = await usrm.CreateAsync(user, UserPassword, _operationCts.Token); return result.Succeeded; } catch (OperationCanceledException) { // 操作已取消,返回失败或做对应处理 return false; } } protected override void Dispose(bool disposing) { if (disposing) { _operationCts.Cancel(); _operationCts.Dispose(); } base.Dispose(disposing); }
内容的提问来源于stack exchange,提问作者wades
相关产品推荐
相关产品推荐

