我有一个用VB.net编写的WPF应用程序。我试图在计时器事件期间访问表单控件,但代码抛出异常。以下是我的代码:
Public WithEvents attendanceFetchTimer As System.Timers.Timer
Private Sub Window_Loaded(sender As Object, e As RoutedEventArgs)
attendanceFetchTimer = New System.Timers.Timer(cfgAttFetchInterval)
AddHandler attendanceFetchTimer.Elapsed, New ElapsedEventHandler(AddressOf getAllDeviceAttendance)
attendanceFetchTimer.Enabled = True
End Sub
Private Sub getAllDeviceAttendance(ByVal sender As Object, ByVal e As ElapsedEventArgs) Handles attendanceFetchTimer.Elapsed
If(checkBox1.isChecked) Then
'Do something here change the textbox value
txtStatus1.Text = "Getting Attendance Data Done!"
End If
End Sub
问题在于,当我调试时,checkBox1.isChecked
显示此消息:
“无法计算表达式,因为我们在无法进行垃圾收集的地方停止,可能是因为可能优化当前方法的代码。”
并在控制台中显示此错误消息:
“WindowsBase.dll中出现'System.InvalidOperationException'类型的第一次机会异常”
当我尝试更改txtStatus1
的文字时会发生同样的问题。
答案 0 :(得分:0)
System.InvalidOperationException
看起来像是由对UI组件的跨线程访问引起的。默认情况下,System.Timers.Timer
会在线程池线程上触发Elapsed
事件。使用DispatcherTimer
和Tick
事件将在正确的线程上获取用于访问WPF中的UI的信息。
由于您同时拥有WithEvents
/ Handles
和AddHandler
,因此看起来您可能有重复的事件处理程序,但我不完全确定它在WPF中是如何工作的。你可能想要(未经测试):
Private attendanceFetchTimer As System.Windows.Threading.DispatcherTimer
Private Sub Window_Loaded(sender As Object, e As RoutedEventArgs)
attendanceFetchTimer = New System.Windows.Threading.DispatcherTimer()
AddHandler attendanceFetchTimer.Tick, AddressOf getAllDeviceAttendance
attendanceFetchTimer.Interval = TimeSpan.FromMilliseconds(cfgAttFetchInterval)
attendanceFetchTimer.Start()
End Sub
Private Sub getAllDeviceAttendance(ByVal sender As Object, ByVal e As EventArgs)
If(checkBox1.isChecked) Then
'Do something here change the textbox value
txtStatus1.Text = "Getting Attendance Data Done!"
End If
End Sub