Visual Basic .NET Language
Einfädeln
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