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

Blazor Server中使用PeriodicTimer刷新组件的最佳实践

定时while循环的最佳放置位置

你当前把循环写在OnInitializedAsync里是有隐患的:

  • Blazor Server默认开启预渲染时,OnInitializedAsync会在预渲染、正式交互两个阶段各执行一次,直接放这里会生成两个并行的定时器循环,产生重复的接口请求。
  • 没有绑定组件生命周期的取消控制,组件销毁后循环不会自动停止,会造成内存泄漏,甚至触发组件释放后的UI更新报错。

正确的放置位置是OnAfterRenderAsync生命周期方法,仅在首次渲染完成(firstRender == true)后启动定时循环。这个时机点组件已经完成和客户端的SignalR连接绑定,也不会受预渲染重复执行逻辑的影响。

PeriodicTimer资源释放的额外处理

你现在仅在Dispose方法中调用_periodicTimer.Dispose()是不够的,还需要补两项处理:

  • 给WaitForNextTickAsync传入和组件生命周期绑定的CancellationToken,组件释放时触发令牌取消,让正在等待定时器的任务主动退出循环,避免任务滞留、触发对象已释放的异常。
  • 捕获循环运行过程中的取消异常、业务请求异常,避免未处理异常导致组件崩溃、上报未捕获任务错误。

修正后的完整实现代码

public partial class Index : IDisposable
{
    private readonly PeriodicTimer _periodicTimer = new(TimeSpan.FromMinutes(1));
    private readonly CancellationTokenSource _disposeCts = new();

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (!firstRender) return;
        
        await Service.Init();
        // 丢弃返回值,不阻塞生命周期方法执行,后台运行定时循环
        _ = ProcessPeriodicRefresh(_disposeCts.Token);
    }

    private async Task ProcessPeriodicRefresh(CancellationToken ct)
    {
        try
        {
            while (await _periodicTimer.WaitForNextTickAsync(ct))
            {
                await Service.GetViewModels();
                await InvokeAsync(StateHasChanged);
            }
        }
        catch (OperationCanceledException)
        {
            // 组件释放触发的正常取消,无需处理
        }
        catch (Exception)
        {
            // 可按需添加日志记录、错误提示等逻辑
        }
    }

    public void Dispose()
    {
        // 先触发取消,终止正在运行的定时任务
        _disposeCts.Cancel();
        _disposeCts.Dispose();
        _periodicTimer.Dispose();
        GC.SuppressFinalize(this);
    }
}

额外注意点

  • 启动定时任务时不要直接await长生命周期的循环任务,否则会阻塞组件生命周期流程,导致页面渲染卡住。
  • 如果你的应用全局关闭了预渲染,理论上也可以在OnInitializedAsync启动循环,但依然建议统一放在OnAfterRenderAsync处理,兼容性更好。
  • 不需要额外手动处理定时器的等待回调,PeriodicTimer本身的WaitForNextTickAsync在收到取消信号、或者定时器被Dispose时都会自动退出等待状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 19:30:10