Task.WaitAll()始终无法完成:DxRichText控件并行初始化异常排查
问题原因与解决方案
核心死锁问题
你在OnInitializedAsync中使用Task.WaitAll()阻塞了当前线程,这是典型的同步阻塞异步代码导致的死锁。Blazor运行在单线程同步上下文环境中,WaitAll会卡住主线程,而后续的异步操作(比如LoadDocumentAsync)需要回到这个上下文才能完成执行,最终形成互相等待的死锁状态,导致代码永远无法返回。
正确的并行处理方式
直接将Task.WaitAll()替换为await Task.WhenAll(),让异步操作以非阻塞的方式等待完成,避免死锁:
var listRichTasks = new List<Task>(); await Task.Yield(); listRichTasks.Add(InitializeRichText(RichEditDesc, _organization, _organization?.Description, Model.Description)); listRichTasks.Add(InitializeRichText(RichEditNews, _organization, _organization?.News, Model.News)); // 替换为await异步等待,不会阻塞同步上下文 await Task.WhenAll(listRichTasks);
额外优化建议
1. HttpClient复用
每次创建HttpClient会额外消耗系统资源,建议通过依赖注入复用同一个实例,或者使用静态实例:
// 组件构造函数注入HttpClient(推荐方式) private readonly HttpClient _httpClient; public YourComponent(HttpClient httpClient) { _httpClient = httpClient; } private async Task LoadUrlAsync(DxRichEdit editor, string url) { using (var response = await _httpClient.GetAsync(url)) { if (response.IsSuccessStatusCode) { await using (var stream = await response.Content.ReadAsStreamAsync()) { await editor.LoadDocumentAsync(stream, DocumentFormat.OpenXml); } } } }
2. ValueTask转Task的注意事项
NewDocumentAsync()返回ValueTask,直接调用.AsTask()包装是可行的,但如果是高频调用场景,尽量避免不必要的包装操作(当前场景下影响可忽略)。
内容的提问来源于stack exchange,提问作者David Thielen
相关产品推荐
相关产品推荐

