Reputation: 467
I'm relatively new to VB.NET and WPF and I have a basic threading question.
I'm just trying to figure out how to use a Timer inside a Page that is using the NavigationService. Here is what I have:
Public Class SplashPage
Inherits Page
Public Sub New(ByVal oData As Object)
StartTimer(5000)
End Sub
Public Sub StartTimer(ByVal iInterval As Double)
Dim timeoutTimer As New System.Timers.Timer
timeoutTimer.Interval = 5000
timeoutTimer.Enabled = True
'Function that gets called after each interval
AddHandler timeoutTimer.Elapsed, AddressOf OnTimedEvent
End Sub
Public Sub OnTimedEvent(source As Object, e As System.Timers.ElapsedEventArgs)
If NavigationService.CanGoBack Then
NavigationService.GoBack()
End If
'MessageBox.Show(e.SignalTime)
End Sub
End Class
The NavigationService.CanGoBack statement is causing the error message: "The calling thread cannot access this object because a different thread owns it."
Any advice or suggestions would be appreciated. Thanks!
Upvotes: 1
Views: 1180
Reputation: 755289
The problem here is that you can't touch UI elements from a background thread. In this scenario the Timer.Elapsed
event fires in a background thread and you get an error when you touch the UI. You need to use SynchronizationContext.Post
to get back to the UI thread before touching the elements
Private context = SynchronizationContext.Current
Public Sub OnTimedEvent(source As Object, e As System.Timers.ElapsedEventArgs)
context.Post(AddressOf OnTimerInMainThread, e)
End Sub
Private Sub OnTimerInMainThread(state as Object)
Dim e = CType(state, ElapsedEventArgs)
If NavigationService.CanGoBack Then
NavigationService.GoBack()
End If
MessageBox.Show(e.SignalTime)
End Sub
Upvotes: 1