Visual Basic .NET Language
Gwintowanie
Szukaj…
Wykonywanie bezpiecznych wątków za pomocą Control.Invoke ()
Za pomocą metody Control.Invoke()
możesz przenieść wykonanie metody lub funkcji z wątku w tle do wątku, w którym formant został utworzony, którym jest zwykle wątek interfejsu użytkownika. W ten sposób kod zostanie umieszczony w kolejce do uruchomienia w wątku kontrolki, co eliminuje możliwość współbieżności.
Należy również sprawdzić właściwość Control.InvokeRequired
, aby ustalić, czy należy wywołać, czy też kod działa już w tym samym wątku co formant.
Metoda Invoke()
przyjmuje delegata jako swój pierwszy parametr. Delegat przechowuje odwołanie, listę parametrów i typ powrotu do innej metody.
W programie Visual Basic 2010 (10.0) lub nowszym wyrażeń lambda można używać do tworzenia metody delegowania w locie:
If LogTextBox.InvokeRequired = True Then
LogTextBox.Invoke(Sub() LogTextBox.AppendText("Check passed"))
Else
LogTextBox.AppendText("Check passed")
End If
Podczas gdy w Visual Basic 2008 (9.0) lub niższej wersji, musisz samodzielnie zadeklarować delegata:
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
Wykonywanie bezpiecznych wątków za pomocą Async / Await
Jeśli spróbujemy zmienić obiekt w wątku interfejsu użytkownika z innego wątku, otrzymamy wyjątek operacji między wątkami:
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
W wersjach wcześniejszych niż VB 14.0 i .NET 4.5 rozwiązanie wywoływało przypisanie i obiekt żyjący w wątku interfejsu użytkownika:
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
W wersji VB 14.0 możemy uruchomić Task
w innym wątku, a następnie przywrócić kontekst po zakończeniu wykonywania, a następnie wykonać przypisanie za pomocą Async / Await:
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