2017-12-06 1 views
0

Wie WindowsFormsSynchronizationContext von einer anderen Klasse und einem Thread aufrufen Wahrscheinlich dumm von meiner Seite, aber ich habe überall gesucht und kann nicht verstehen.WindowsFormsSynchronizationContext von einer anderen Klasse

Es funktioniert, wenn ich den Arbeiter und Code in den Körper von Form1 einfügen.

Form1:

Public Shared UIContext As WindowsFormsSynchronizationContext 
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click 
    UIContext = WindowsFormsSynchronizationContext.Current 
    Dim StartClock As New SendtoUI 
End Sub 
Public Sub updatelable(incomingText As String) 
    Label1.Text = incomingText 
End Sub 

Testklasse:

Public Class SendtoUI 
    Private lastUpdated As DateTime = DateTime.Now 
    Private backgroundTimer As System.Timers.Timer 
    Public Sub New() 
     backgroundTimer = New Timers.Timer(1000) 
     AddHandler backgroundTimer.Elapsed, New System.Timers.ElapsedEventHandler(AddressOf backgroundTimer_Elapsed) 
     backgroundTimer.Start() 
    End Sub 

    Private Sub backgroundTimer_Elapsed(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs) 
     lastUpdated = DateTime.Now 

     Form1.UIContext.Post(Sub() 
            Form1.updatelable(lastUpdated.ToLongTimeString()) 
           End Sub, Nothing) 
    End Sub 
End Class 

auf oben Basierend

Label1.Text = incomingText

Die Linie bekommt e ausgeführt, aber das Label wird nicht aktualisiert. Wahrscheinlich so einfach, aber ich bin ratlos.

Danke für jede Hilfe!

-TD

OK, dachte ich, es dank Jimi aus, ich bin Aktualisierung mit dem, was ich am Ende mit und hoffentlich kann es jemand anderes helfen!

Einfach form1 wie folgt:

Imports System.Threading 

    Public Class Form1 
     Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 
      Dim TestTHreadUI As New ThreadedBackground(SynchronizationContext.Current, New SendOrPostCallback(AddressOf UpdateUI)) 
     End Sub 
     Public Sub UpdateUI(incomingText As Object) 
      Label1.Text = incomingText.ToString 
     End Sub 
    End Class 

ThreadedBackground Klasse:

Imports System.Threading 

    Public Class ThreadedBackground 
     Private backgroundTimer As System.Timers.Timer 
     Public Sub New(UIContext As SynchronizationContext, UpdateAddress As SendOrPostCallback) 
      SyncContext = UIContext 
      SyncCallback = UpdateAddress 
      backgroundTimer = New Timers.Timer(1000) 
      AddHandler backgroundTimer.Elapsed, New System.Timers.ElapsedEventHandler(AddressOf backgroundTimer_Elapsed) 
      backgroundTimer.Start() 
     End Sub 

     'SynchronizationContext used for Posting 
     Public Property SyncContext As System.Threading.SynchronizationContext 
     'The Object Callback address to call 
     Public Property SyncCallback As System.Threading.SendOrPostCallback 

     Private Sub backgroundTimer_Elapsed(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs) 

      'SyncContext.Post(SyncCallback, CType(DateTime.Now.ToLongTimeString, Object)) ' using passed in SendOrPostCallback(SyncCallback) 
      SyncContext.Post(New SendOrPostCallback(Sub() Form1.UpdateUI(DateTime.Now.ToLongTimeString)), Nothing) ' Not using SendOrPostCallback(SyncCallback), Direct call to form1 Sub using lambda 
      'SyncContext.Post(New SendOrPostCallback(Sub() Form1.Label1.Text = DateTime.Now.ToLongTimeString), Nothing) ' Not using SendOrPostCallback(SyncCallback), Direct call to form1 Control using lambda 

     End Sub 
    End Class 

Antwort

0

I'ld betrachtet einen statischen Verweis auf ein bestimmtes Objekt (Formular in diesem Fall) in der Klasse zu vermeiden.
Eine Möglichkeit besteht darin, Ihrer Klasse einige Eigenschaften hinzuzufügen, die diese Referenz enthalten können.

Imports System.Threading 

Public Class Form1 

    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button1.Click 

     Dim StartClock As New SendtoUI 
     StartClock.SyncContext = System.Windows.Forms.WindowsFormsSynchronizationContext.Current 
     StartClock.SyncCallback = New System.Threading.SendOrPostCallback(AddressOf Me.updatelable) 
    End Sub 

    'Delegate signature 
    'Public Delegate Sub SendOrPostCallback(state As Object) 

    Public Sub updatelable(incomingText As Object) 
     Label1.Text = incomingText.ToString 
    End Sub 
End Class 

Ihre Klasse mit neuen Eigenschaften:

Ihr Code kann als bearbeitet werden

Public Class SendtoUI 
    Private backgroundTimer As System.Timers.Timer 
    Public Sub New() 
     backgroundTimer = New Timers.Timer(1000) 
     AddHandler backgroundTimer.Elapsed, New System.Timers.ElapsedEventHandler(AddressOf backgroundTimer_Elapsed) 
     backgroundTimer.Start() 
    End Sub 

    'SynchronizationContext used for Posting 
    Public Property SyncContext As System.Threading.SynchronizationContext 
    'The Object Callback address to call 
    Public Property SyncCallback As System.Threading.SendOrPostCallback 

    Private Sub backgroundTimer_Elapsed(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs) 

     SyncContext.Post(SyncCallback, CType(DateTime.Now.ToLongTimeString, Object)) 

    End Sub 
End Class 
+0

Ich werde dies als beantwortet markieren! Und danke, ich wollte mehr fragen, aber meine ursprüngliche Absicht war es, SendUI agnostisch zu behalten ... von anderen Formen angerufen zu werden und das tut es gerade so Danke, also ich war dumm lol, Allerdings, keine Notwendigkeit zu antworten, aber meine ursprüngliche Form1.UIContext.Post (Sub() Ich habe in anderen Orten verwiesen gesehen und dachte, es sollte funktionieren, können Sie erklären, warum nicht? Nochmals vielen Dank .... –

+0

@TD_Home Haben Sie versucht, in Ihrem Projekt zu setzen, Option Explicit: ON und Option Strict: ON? Wenn Sie dies tun, wird das Problem sofort angezeigt: Sie haben 'WindowsFormsSynchronizationContext.Current', das einer statischen Variable zugewiesen ist, die als' Public Shared UIContext As WindowsFormsSynchronizationContext' definiert ist. Was ist daran falsch? – Jimi

+0

Ich bin gut, danke für die Hilfe! –

Verwandte Themen