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

在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实现,需要做如下修改:

  1. 将Timer声明为组件全局字段,避免被GC回收
  2. 回调中用InvokeAsync切回UI线程修改状态,手动调用StateHasChanged触发重渲染
  3. 组件销毁时释放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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 21:09:02