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

Blazor WASM定时器运行数次后随机停止问题求助

Blazor WASM定时器随机停止的原因与解决方法

核心原因:定时器实例被垃圾回收

你定义的t2是局部变量,当代码执行完创建定时器的逻辑后,没有任何持久化的引用指向这个定时器实例。.NET的垃圾回收器(GC)会在后续的回收周期中把它标记为可回收对象并清理,定时器自然就停止工作了。

解决方案

1. 将定时器实例保存为组件字段

把t2从局部变量改为组件的私有字段,确保组件生命周期内始终有引用指向它,避免被GC回收:

// 在组件类中定义字段
private Timer? _updateTimer;

// 在合适的生命周期方法(比如OnInitializedAsync)中初始化定时器
protected override void OnInitialized()
{
    _updateTimer = new Timer(async state =>
    {
        await UpdateCurrentConsumptionData();
    }, null, 3000, 5000);
}

2. 处理异步回调的异常

Timer的回调是async void类型(因为TimerCallback委托返回void),如果UpdateCurrentConsumptionData中抛出未处理异常,会直接终止定时器甚至整个应用。要在回调中捕获异常:

_updateTimer = new Timer(async state =>
{
    try
    {
        await UpdateCurrentConsumptionData();
    }
    catch (Exception ex)
    {
        // 这里可以记录日志或处理异常,比如输出到控制台
        Console.WriteLine($"定时器执行失败: {ex.Message}");
    }
}, null, 3000, 5000);

3. 组件销毁时释放定时器资源

在组件的Dispose方法中释放定时器,避免内存泄漏:

public void Dispose()
{
    _updateTimer?.Dispose();
}

注意:如果组件实现了IDisposable接口,记得在组件类中声明:

public class YourComponent : ComponentBase, IDisposable
{
    // ... 其他代码 ...

    public void Dispose()
    {
        _updateTimer?.Dispose();
    }
}

额外优化建议

  • 在Blazor组件中调用StateHasChanged()时,最好确保在UI线程执行。虽然WASM中默认是单线程,但如果有特殊情况,可以用InvokeAsync(StateHasChanged)来保证线程安全:
private async Task UpdateCurrentConsumptionData()
{
    var http = httpClientSelector!.GetNoAuthHttpClient();
    currentPowerConsumptionData = await http.GetFromJsonAsync<Shared.Models.GenericInfluxDatapoint>(Config.URL_GET_DASHBOARD_CURRENT_POWER_CONSUMPTION_DATA);
    await InvokeAsync(StateHasChanged());          
}

内容的提问来源于stack exchange,提问作者Mr. Muh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 14:36:21