使用Identity用户登录时调用PasswordSignInAsync出现死锁问题
Blazor Server(.NET Core 7)Identity登录死锁及类型转换错误解决
问题根源
你的代码出现死锁和类型错误的核心原因是错误地用同步方式调用异步方法:
- Blazor Server基于单线程同步上下文运行,当你调用异步方法时使用
.Result或.Wait(),当前线程会被阻塞等待任务完成;而异步任务执行完毕后需要回到原同步上下文继续处理,但原线程已被阻塞,最终形成死锁,导致Task状态一直停留在WaitForActivation,程序卡住无响应。 - 后续修改时将方法改为异步但调用时未使用
await,导致Task<string>无法直接转换为string,触发CS0029错误。
解决方案
1. 将验证方法改为全异步实现
把checkIdentity改为异步方法,用await替代所有.Result调用:
[Inject] public UserManager<IdentityUser> userManager { get; set; } [Inject] public RoleManager<IdentityRole> roleManager { get; set; } [Inject] public SignInManager<IdentityUser> signInManager { get; set; } // 重命名方法为符合异步规范的名称,返回Task<string> public async Task<string> CheckIdentityAsync() { string msg = null; UserDto userDto = new UserDto(); userDto.UserName = UserName; userDto.Password = Password; var user = await userManager.FindByNameAsync(userDto.UserName); if (user != null) { var passwordCheck = await userManager.CheckPasswordAsync(user, "Coding@1234?"); if (passwordCheck) { var signInResult = await signInManager.PasswordSignInAsync(userDto.UserName, "Coding@1234?", false, false); // 可根据SignInResult状态补充逻辑 msg = signInResult.Succeeded ? "登录成功" : $"登录失败:{signInResult.ToString()}"; } else { msg = "密码验证失败"; } } else { msg = "用户不存在"; } return msg; }
2. 异步调用验证方法
在调用CheckIdentityAsync的地方必须使用await,比如组件的按钮点击事件中:
// 示例:组件内的登录处理方法 private async Task HandleLogin() { string resultMsg = await CheckIdentityAsync(); // 后续处理结果,比如显示提示信息 }
发布后问题是否会出现
会出现死锁问题。死锁是由Blazor Server的同步上下文机制和错误的异步调用方式导致的,和调试环境无关。只要代码中保留.Result/.Wait()这类阻塞异步方法的写法,无论调试还是发布运行,都会触发死锁。
内容的提问来源于stack exchange,提问作者ahmed abdelaziz
相关产品推荐
相关产品推荐

