zzMzz
zzMzz

Reputation: 467

VB.NET WPF Threading

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

Answers (1)

JaredPar
JaredPar

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

Related Questions