意外递归Sub问题:PopulateStatusBar重复执行求助
问题修复方案
1. 修复定时器配置错误
你当前PerformLoadMe方法里创建的System.Timers.Timer未设置触发间隔(Interval),默认值为0,结合AutoReset=True会导致定时器疯狂触发Elapsed事件,这是PopulateStatusBar重复执行的核心原因之一。
修改代码如下:
Private Sub PerformLoadMe() ' 设置定时器间隔为1秒(1000毫秒),可根据需求调整 Dim tmr As New System.Timers.Timer With {.Interval = 1000, .AutoReset = True} AddHandler tmr.Elapsed, AddressOf PopulateStatusBar tmr.Enabled = True ' 最后启用定时器 PopulateStatusBar() ' 初始化调用一次 End Sub
2. 避免属性赋值触发递归
如果AtlanticLabel是实现INotifyPropertyChanged的绑定属性,需确保属性赋值不会间接触发PopulateStatusBar重复调用。同时改用局部变量统一计算基准时间,避免全局变量引发的意外逻辑:
Private Sub PopulateStatusBar() ' 一次性获取UTC时间,作为所有时区计算的基准 Dim utcNow As Date = Date.UtcNow ' 大西洋时区时间计算 Dim atlanticZone As TimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Atlantic Standard Time") Dim atlanticLocal As Date = TimeZoneInfo.ConvertTimeFromUtc(utcNow, atlanticZone) AtlanticLabel = $" Atlantic {atlanticLocal.ToString("ddd HH:mm")} " ' 其他时区计算同理,全部基于同一个utcNow值 ' ... End Sub
3. 处理定时器的线程安全问题
System.Timers.Timer的Elapsed事件在ThreadPool线程触发,直接更新WPF UI会引发线程异常,需切换到UI线程执行:
' 适配定时器Elapsed事件的重载方法 Private Sub PopulateStatusBar(sender As Object, e As ElapsedEventArgs) PopulateStatusBar() End Sub Private Sub PopulateStatusBar() ' 检查是否需要切换到UI线程 If Application.Current.Dispatcher.CheckAccess() = False Then Application.Current.Dispatcher.Invoke(AddressOf PopulateStatusBar) Return End If Dim utcNow As Date = Date.UtcNow ' 后续时间计算与UI赋值逻辑同上 ' ... End Sub
额外检查项
- 排查是否有其他事件(如UI的
Loaded、属性PropertyChanged)重复绑定了PopulateStatusBar - 确认
RelayCommand的CanExecute逻辑不会导致命令被重复触发
内容的提问来源于stack exchange,提问作者SezMe
相关产品推荐
相关产品推荐

