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

Server Side Blazor加载状态Spinner无法显示问题求助

让我来帮你搞定这个Spinner不显示的问题!核心问题出在你的WeatherForecastService里的同步阻塞操作,直接卡死了UI线程,导致Spinner根本没机会渲染出来。

问题根源分析

你在服务里写的Task.Delay(5000).Wait()是同步等待,这会把Blazor的主线程挂起整整5秒。期间UI完全无法更新,哪怕你在组件里设置了loading=true,也因为线程被阻塞,Blazor没时间去重新渲染界面,Spinner自然就看不到了。

解决方案步骤

1. 修复WeatherForecastService的异步逻辑

把同步等待改成异步await,让线程在等待期间释放回线程池,给UI更新留出生存空间:

public async Task<WeatherForecast[]> GetForecastAsync(DateTime startDate) 
{ 
    var rng = new Random(); 
    await Task.Delay(5000); // 用await替代Wait(),避免阻塞主线程
    return Enumerable.Range(1, 5).Select(index => new WeatherForecast { 
        Date = startDate.AddDays(index), 
        TemperatureC = rng.Next(-20, 55), 
        Summary = Summaries[rng.Next(Summaries.Length)] 
    }).ToArray(); 
}

2. 优化FetchData.razor的UI逻辑

其实你的组件代码大部分是对的,但可以去掉多余的手动状态更新调用——Blazor在异步方法的暂停点会自动触发UI更新。这里给你补全完整的可运行代码:

<h1>Weather forecast</h1> 

@if (loading) { 
    <div class="spinner-border text-primary" role="status">
        <span class="visually-hidden">Loading...</span>
    </div> 
} 

@if (forecasts == null) { 
    <button class="btn btn-primary mt-3" @onclick="@LoadForecasts">Load Weather Data</button> 
} else {
    <table class="table mt-3">
        <thead>
            <tr>
                <th>Date</th>
                <th>Temperature (C)</th>
                <th>Temperature (F)</th>
                <th>Summary</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var forecast in forecasts)
            {
                <tr>
                    <td>@forecast.Date.ToShortDateString()</td>
                    <td>@forecast.TemperatureC</td>
                    <td>@forecast.TemperatureF</td>
                    <td>@forecast.Summary</td>
                </tr>
            }
        </tbody>
    </table>
}

@code { 
    private WeatherForecast[] forecasts; 
    private bool loading = false; 

    // 确保注入服务(如果之前没加的话)
    [Inject]
    private WeatherForecastService ForecastService { get; set; }

    private async Task LoadForecasts() { 
        loading = true; 
        // 这里不需要手动调用StateHasChanged(),Blazor会在await后自动更新UI
        forecasts = await ForecastService.GetForecastAsync(DateTime.Now); 
        loading = false; 
    } 
}

为什么这样改能生效?

  • 服务里的await Task.Delay(5000)会让当前方法暂停,把线程还给线程池,Blazor就能趁机更新UI,显示Spinner。
  • 组件里的异步方法执行到await时,Blazor会自动注册一个回调,在异步操作完成后触发UI更新,所以不需要手动调用StateHasChanged()。

现在点击按钮,你应该就能看到加载中的Spinner了!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 13:47:38