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

