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


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow