在Blazor中如何实现div显示5秒后自动隐藏?
问题原因
你遇到的InvalidOperationException异常是因为System.Timers.Timer的Elapsed回调默认运行在后台线程池线程,Blazor不允许在非UI同步上下文直接修改组件状态变量,且后台线程修改状态后也不会自动触发UI重渲染。同时你将Timer定义为方法内局部变量,运行过程中可能被GC回收导致回调不触发。
正确实现方案
推荐用更简洁的Task.Delay方案,不需要处理定时器资源和线程切换问题:
@if (alertMessageShow) { <div class="alert alert-success" style="margin-left: 50px"> 您的修改已保存 </div> } <RadzenButton Icon="add_circle_outline" style="margin-bottom: 10px" Text="Nani" Click="@alertMessage" /> @code { bool alertMessageShow = false; async Task alertMessage() { alertMessageShow = true; // 延迟5秒 await Task.Delay(5000); alertMessageShow = false; } }
await Task.Delay结束后会自动切回Blazor UI同步上下文,修改状态后会自动触发UI重渲染,不会抛出线程相关异常。
如果你坚持使用Timer实现,需要做如下修改:
- 将Timer声明为组件全局字段,避免被GC回收
- 回调中用
InvokeAsync切回UI线程修改状态,手动调用StateHasChanged触发重渲染 - 组件销毁时释放Timer避免内存泄漏
@implements IDisposable @* 其余UI代码不变 *@ @code { bool alertMessageShow = false; private System.Timers.Timer _alertTimer; void alertMessage() { alertMessageShow = true; // 销毁之前的定时器,避免多次点击触发多个计时 _alertTimer?.Dispose(); _alertTimer = new System.Timers.Timer(5000); _alertTimer.Elapsed += AlertTimerElapsed; // 仅触发一次 _alertTimer.AutoReset = false; _alertTimer.Start(); } private async void AlertTimerElapsed(object source, System.Timers.ElapsedEventArgs e) { await InvokeAsync(() => { alertMessageShow = false; StateHasChanged(); }); } public void Dispose() { _alertTimer?.Dispose(); } }
内容的提问来源于stack exchange,提问作者jacky
相关产品推荐
相关产品推荐

