Ricerca…


Esecuzione di chiamate thread-safe tramite Control.Invoke ()

Utilizzando il metodo Control.Invoke() è possibile spostare l'esecuzione di un metodo o una funzione da un thread in background al thread su cui è stato creato il controllo, che di solito è il thread dell'interfaccia utente (User Interface). In questo modo il codice verrà messo in coda per l'esecuzione sul thread del controllo, che rimuoverà la possibilità di concorrenza.

La proprietà Control.InvokeRequired dovrebbe inoltre essere controllata per determinare se è necessario richiamare o se il codice è già in esecuzione sullo stesso thread del controllo.

Il metodo Invoke() accetta un delegato come primo parametro. Un delegato mantiene il riferimento, l'elenco dei parametri e il tipo restituito con un altro metodo.

In Visual Basic 2010 (10.0) o versioni successive, è possibile utilizzare espressioni lambda per creare al volo un metodo delegato:

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

Considerando che in Visual Basic 2008 (9.0) o inferiore, è necessario dichiarare il delegato per conto proprio:

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

Esecuzione di chiamate thread-safe usando Async / Attesa

Se proviamo a cambiare un oggetto sul thread dell'interfaccia utente da un thread diverso, otterremo un'eccezione di operazione cross-thread:

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

Prima di VB 14.0 e .NET 4.5 la soluzione stava invocando l'assegnazione on e object living sul thread dell'interfaccia utente:

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

Con VB 14.0, possiamo eseguire Task su un thread diverso e quindi sfruttare al contesto ripristinata quando l'esecuzione è completa e quindi eseguire l'assegnazione con asincrono / 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
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow