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
相关产品推荐
相关产品推荐

