You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Blazor Server中启动Task导致应用停滞问题求助

问题分析与解决方案

核心问题

代码执行停滞的根源是同步阻塞引发的死锁,再加上异步方法误用、冗余代码以及反序列化错误,具体问题点:

  • async void方法脱离Blazor组件生命周期管理,无法追踪异步状态,异常还会直接导致应用崩溃
  • task.Wait()会阻塞Blazor的同步上下文,而后续await操作需要回到该上下文,形成互相等待的死锁
  • GetJsonString中手动创建TaskCompletionSource属于冗余操作,完全没必要
  • 反序列化时将单个Quotation强制转为IEnumerable<Quotation>,会抛出类型转换异常

修正后的完整代码

public static IEnumerable<Quotation> customerQuotations = Array.Empty<Quotation>();

// 改为async Task,等待异步操作完成
public async Task CustomerRowSelectHandler(RowSelectEventArgs<Customer> args)
{
    await GetCustomerQuotes(args.Data.customerId);
}

// 替换async void为async Task,支持await等待
static async Task GetCustomerQuotes(int customerId)
{
    string url = string.Format(@"https://my.server.dns/quotations/customer/{0}", customerId);
    // 用await替代Wait(),避免阻塞同步上下文
    var jsonString = await GetJsonString(url);
    // 修正反序列化类型,直接反序列化为目标集合类型
    customerQuotations = JsonConvert.DeserializeObject<IEnumerable<Quotation>>(jsonString) ?? Array.Empty<Quotation>();
}

// 简化异步方法,移除冗余的TaskCompletionSource
private static async Task<string> GetJsonString(string url)
{
    // 建议:不要每次调用都新建HttpClient,Blazor Server中可通过依赖注入IHttpClientFactory复用实例,避免socket耗尽
    var myClient = new HttpClient(new HttpClientHandler() { UseDefaultCredentials = true });
    HttpResponseMessage response = await myClient.GetAsync(url);
    // 确保请求成功,否则抛出异常
    response.EnsureSuccessStatusCode();
    return await response.Content.ReadAsStringAsync();
}

额外优化建议

  • 复用HttpClient:避免每次请求都创建新的HttpClient,通过依赖注入IHttpClientFactory获取实例,提升性能并避免资源泄漏
  • 替换静态变量:customerQuotations作为静态变量,在多用户场景下会导致数据混乱,建议改为组件实例变量,若需更新UI,可调用StateHasChanged()通知组件刷新

内容的提问来源于stack exchange,提问作者SkinnyPete63

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 09:30:50