Threadsicherheit mit Parameterübergabe

  • VB.NET

Es gibt 6 Antworten in diesem Thema. Der letzte Beitrag () ist von jvbsl.

    Threadsicherheit mit Parameterübergabe

    Hallo zusammen!

    Da VB bzw. die Forms ja nicht Threadsicher ist, muss ich Änderungen an Steuerelementen aus Threads heraus über Deleganten regeln!

    Sowas hier:

    VB.NET-Quellcode

    1. If Label15.InvokeRequired = True Then
    2. Label1.Invalidate(New MethodInvoker(AddressOf invokeLb1))
    3. Else
    4. invokeLb1()
    5. End If


    So weit so gut!
    Aber wie mache ich das, wenn invokeLb1 einen Parameter erwatet?
    wie kann ich also über einen Deleganten einen Parameter übergeben?

    Gruß Mechatron :)

    _______________________________________________________________

    Nachtrag:
    So sollte es aussehen:

    VB.NET-Quellcode

    1. If Label15.InvokeRequired = True Then
    2. Label1.Invoke(New MethodInvoker(AddressOf invokeLb1))
    3. Else
    4. invokeLb1()
    5. End If

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Mechatron“ ()

    Der MethodInvoker ist ein vordefinierter Delegate ohne Argumente, d.h. er ist definiert als

    VB.NET-Quellcode

    1. Delegate Sub MethodInvoker()

    Für Delegaten mit Argumenten nimmt man entweder andere in VB schon vorgegebene Delegaten oder man definiert sie sich selbst:

    VB.NET-Quellcode

    1. Friend Delegate Sub stringDelegate(ByVal s As String)
    2. Me.Invoke(New stringDelegate(AddressOf InvokeLB1), "Hello World")
    3. Sub InvokeLB1(ByVal s As String)
    4. ' ....
    5. End Sub

    Kleiner Nachtrag: man kann das switchen auf den ControlThread auch der Funktion selbst überlassen, ungefähr so:

    VB.NET-Quellcode

    1. Sub InvokeLB1(ByVal s As String)
    2. ' switchen auf Control Thread
    3. If Me.InvokeRequired Then Me.Invoke(New stringDelegate(AddressOf InvokeLB1), s):Return
    4. ' rest des codes
    5. End Sub

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Kangaroo“ ()

    Hallo,

    Warum müssen Delegationen benutzt werden um Threadübergreifend arbeiten zu können?
    Ein Thread arbeitet immer nur auf seiner eigenen "Ebene" und keinen Zugriff auf andere Ebenen, da dadurch viele Probleme wie Deadlocks entstehen könnten. Deswegen kann ein Thread nur Funktionen und Ressourcen nutzen, die unter seiner eigenen Prozess ID laufen.

    Wenn du nun also zwei Klassen hast die in unterschiedlichen Threads laufen, und du Mit Thread A auf Thread B zugreifen willst musst du dem Aufruf von Thread A "innnerhalb" von Thread B aufrufen. Das funktioniert mit delegeten Funktionen.

    Einfach ausgedrückt leitest du eine Funktion über einen Delegaten Aufruf in den Thread weiter, sodass der Aufruf die selbe ID hat wie der ehemals fremde Thread und somit keine Probleme Verursacht. Und natürlich kannst du auch Parameter übergeben, zB. so:

    Zunächst brauchst du eine Delegate Funktion ,die deinen Aufruf in den anderen Thread weiterleitet:

    VB.NET-Quellcode

    1. Public Delegate Function refreshImageDel _
    2. (ByVal pfad As String)


    Wie du siehst nimmt diese Funktion eiinen Parameter vom Typ String an

    Als zweites musst du nun eine Funktion implementieren die die selbe Sgnatur hat:

    VB.NET-Quellcode

    1. Public Function refreshImage(ByVal pfad As String)
    2. Try
    3. Me.imgMain.Image = Image.FromFile(pfad)
    4. Catch ex As Exception
    5. End Try
    6. Return Nothing
    7. End Function


    Nun kannst du aus einem Beliebigen Thread diese Funktion aufrufen:

    VB.NET-Quellcode

    1. Dim s As String = "C:\bla.bmp"
    2. Me.Invoke(New refreshImageDel(AddressOf refreshImage), New Object() {s})


    Der zweite parameter von Me.Invoke nimmt als Parameter einen Object Array, der die parameter beinhaltet. Diese Parameter werden dann abhängig von der Signatur deiner Funktion auf deren Parameter gemappt das geschießt hierbei sequentionell.

    Das wars dann auch schon! ;)

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „bigbasti“ ()