Suche…


Thread-sichere Aufrufe mit Control.Invoke () durchführen

Mit der Control.Invoke() Methode können Sie die Ausführung einer Methode oder Funktion von einem Hintergrund-Thread in den Thread verschieben, in dem das Steuerelement erstellt wurde. Control.Invoke() ist normalerweise der UI-Thread (User Interface). Auf diese Weise wird Ihr Code in die Warteschlange gestellt, um stattdessen im Thread des Steuerelements ausgeführt zu werden, wodurch die Möglichkeit der Parallelität beseitigt wird.

Die Control.InvokeRequired Eigenschaft sollte auch überprüft werden, um festzustellen, ob Sie aufrufen müssen oder ob der Code bereits im selben Thread wie das Steuerelement ausgeführt wird.

Die Invoke() Methode nimmt einen Delegaten als ersten Parameter. Ein Delegat enthält die Referenz, die Parameterliste und den Rückgabetyp für eine andere Methode.

In Visual Basic 2010 (10.0) oder höher können Lambda-Ausdrücke verwendet werden, um spontan eine Delegat-Methode zu erstellen:

If LogTextBox.InvokeRequired = True Then
    LogTextBox.Invoke(Sub() LogTextBox.AppendText("Check passed"))
Else
    LogTextBox.AppendText("Check passed")
End If

In Visual Basic 2008 (9.0) oder niedriger müssen Sie den Delegierten jedoch selbst deklarieren:

Delegate Sub AddLogText(ByVal Text As String)

If LogTextBox.InvokeRequired = True Then
    LogTextBox.Invoke(New AddLogText(AddressOf UpdateLog), "Check passed")
Else
    UpdateLog("Check passed")
End If

Sub UpdateLog(ByVal Text As String)
    LogTextBox.AppendText(Text)
End Sub

Thread-sichere Anrufe mit Async / Await durchführen

Wenn wir versuchen, ein Objekt im UI-Thread von einem anderen Thread aus zu ändern, wird eine Cross-Thread-Operationsausnahme angezeigt:

Private Sub Button_Click(sender As Object, e As EventArgs) Handles MyButton.Click
    ' Cross thread-operation exception as the assignment is executed on a different thread
    ' from the UI one:
    Task.Run(Sub() MyButton.Text = Thread.CurrentThread.ManagedThreadId)
End Sub

Vor VB 14.0 und .NET 4.5 hat die Lösung die Zuweisung auf und das Objekt auf dem UI-Thread aufgerufen:

Private Sub Button_Click(sender As Object, e As EventArgs) Handles MyButton.Click
    ' This will run the conde on the UI thread:
    MyButton.Invoke(Sub() MyButton.Text = Thread.CurrentThread.ManagedThreadId)
End Sub

Mit VB 14.0 können wir eine Task in einem anderen Thread ausführen und dann den Kontext wiederherstellen, sobald die Ausführung abgeschlossen ist, und dann die Zuweisung mit Async / Await durchführen:

Private Async Sub Button_Click(sender As Object, e As EventArgs) Handles MyButton.Click
    ' This will run the code on a different thread then the context is restored
    ' so the assignment happens on the UI thread:
    MyButton.Text = Await Task.Run(Function() Thread.CurrentThread.ManagedThreadId)
End Sub


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow