Visual Basic .NET Language
Enhebrado
Buscar..
Realizar llamadas a prueba de subprocesos usando Control.Invoke ()
Usando el método Control.Invoke()
, puede mover la ejecución de un método o función desde un hilo de fondo al hilo en el que se creó el control, que generalmente es el hilo de la interfaz de usuario. Al hacerlo, su código se pondrá en cola para ejecutarse en el subproceso del control, lo que elimina la posibilidad de concurrencia.
La propiedad Control.InvokeRequired
también debe verificarse para determinar si necesita invocar o si el código ya se está ejecutando en el mismo hilo que el control.
El método Invoke()
toma un delegado como primer parámetro. Un delegado mantiene la referencia, la lista de parámetros y el tipo de retorno a otro método.
En Visual Basic 2010 (10.0) o superior, las expresiones lambda se pueden usar para crear un método delegado sobre la marcha:
If LogTextBox.InvokeRequired = True Then
LogTextBox.Invoke(Sub() LogTextBox.AppendText("Check passed"))
Else
LogTextBox.AppendText("Check passed")
End If
Mientras que en Visual Basic 2008 (9.0) o inferior, debes declarar al delegado por tu cuenta:
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
Realizar llamadas a prueba de subprocesos utilizando Async / Await
Si intentamos cambiar un objeto en el subproceso de la interfaz de usuario desde un subproceso diferente, obtendremos una excepción de operación entre subprocesos:
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
Antes de VB 14.0 y .NET 4.5, la solución invocaba la asignación y el objeto que viven en el hilo de la interfaz de usuario:
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 , podemos ejecutar una Task
en un subproceso diferente y luego restaurar el contexto una vez que se completa la ejecución y luego realizar la asignación con 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