Blazor中SaveChangesAsync.Wait()无响应的原因排查
问题根源:同步阻塞异步代码导致死锁
你遇到的是典型的异步同步混用引发的死锁,具体逻辑如下:
- Blazor运行时会维护一个同步上下文(SynchronizationContext),负责调度UI线程任务,确保UI操作、状态更新在单线程执行。
- 当你调用
SaveChangesAsync().Wait()时,Wait()会阻塞当前UI线程,等待异步操作完成。 SaveChangesAsync完成数据库操作后,需要回到原同步上下文执行后续逻辑(如资源释放、状态变更触发),但此时同步上下文已被阻塞的UI线程占用,异步回调无法推进,最终形成互相等待的死锁。- 数据库能完成更新,是因为数据库操作本身已在后台异步执行完毕,但后续回调步骤被卡住,导致
Wait()一直处于等待状态。
正确解决方式
全程遵循异步编程模型,避免同步阻塞异步代码:
- 将
Run方法改为异步方法:
private async Task RunAsync() { try { var id = Guid.Parse("5C7B0B3D-08FA-406D-ABCA-18EE33321B55"); var data = DbContext.Set<MyModel>().AsTracking(QueryTrackingBehavior.TrackAll) .Single(x => x.Id == id); data.UpdateDate = DateTimeOffset.Now; } finally { await DbContext.SaveChangesAsync(CancellationToken.None); } }
- 在调用处通过
await执行异步方法:
private async Task HandleValidSubmit() { await RunAsync(); await JS.InvokeVoidAsync("swalInfo", null, "Demo"); }
这种写法完全贴合异步编程规范,不会阻塞同步上下文,自然就能避免死锁问题。
内容的提问来源于stack exchange,提问作者kursat sonmez
相关产品推荐
相关产品推荐

