unity thread net form example ejemplo delegate checkforillegalcrossthreadcalls .net vb.net invoke hang

.net - thread - Control.Invoke está colgando



invoke vb net (2)

Está utilizando Thread.Join para dejar que el hilo de la interfaz de usuario se detenga hasta que Thread.Join el otro hilo. Al mismo tiempo, utiliza Control.Invoke para permitir que el subproceso de la interfaz de usuario realice alguna acción. Esto no funcionará porque el subproceso de la interfaz de usuario está esperando que termine el otro subproceso.

Le sugiero que elimine la llamada de Thread.Join o realice su acción en el hilo de UI si desea que espere a que termine la acción.

He visto un montón de publicaciones relacionadas con el problema del control. Invoco aplicaciones colgantes, pero en su mayoría parecían estar restringidas a las que se ejecutan en .NET 1.1. También he visto sugerencias para utilizar .BeginInvoke en su lugar, lo he intentado pero fue en vano. .BeginInvoke no se bloquea, pero tampoco llama al delegado. Mi principal preocupación es que he usado. Invoco durante años sin problemas y tengo una gran aplicación en el campo que lo usa ampliamente y me preocupa que este problema surja allí. No estoy haciendo nada diferente, por lo que puedo decir, entre mi código de trabajo y el código que falla. He escrito un bit de código simple que reproduce el problema (todo en 4.0 VS2010):

Public Class Form1 Private WithEvents sat As TestInvoke Private Delegate Sub doTheUpdateDelegate(ByVal message As String) Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click sat = New TestInvoke sat.startAThread() End Sub Public Class TestInvoke Public Event UpdateControl() Public Sub startAThread() Dim t As New Threading.Thread(AddressOf _startAThread) Dim trace As String trace = "a" t.SetApartmentState(Threading.ApartmentState.STA) t.Start() t.Join() End Sub Protected Sub _startAThread() Try For k = 0 To 10 System.Threading.Thread.Sleep(1000) k += 1 RaiseEvent UpdateControl() Next Catch ex As Exception MsgBox(ex.Message) End Try End Sub End Class Private Sub sat_UpdateControl() Handles sat.UpdateControl Try Call doTheupdate(Now.ToString) Catch ex As Exception MsgBox(ex.Message) End Try End Sub Private Sub doTheUpdate(ByVal message As String) Try If Button1.InvokeRequired = True Then Dim objParams As Object() = {message} ''hangs on the following line Button1.Invoke(New doTheUpdateDelegate(AddressOf doTheUpdate), objParams) Else Button1.Text = message End If Catch ex As Exception MsgBox(ex.Message) End Try End Sub End Class

Si alguien puede ver lo que he hecho mal aquí, ¡realmente lo agradecería!


Solo hay una razón por la que se cuelgue una llamada Control.Invoke (). O una llamada BeginInvoke () no ejecuta su objetivo, lo mismo. Sucede cuando el hilo principal del programa, el hilo de UI, no está inactivo y ocupado haciendo otra cosa.

Lo que la "otra cosa" podría ser está en todo el mapa. Lo peor que podría hacer es que el hilo principal espere a que se complete el hilo del trabajador. Es un punto muerto garantizado si usa Invoke ().

La condición es muy fácil de diagnosticar, use Debug + Break All y Debug + Windows + Threads. Haga doble clic en el hilo principal y observe la ventana Pila de llamadas. La parte superior de la traza de la pila debe decir "Transición gestionada a nativa", la siguiente debajo debe ser FPushMessageLoop (). Si ves algo más, entonces has encontrado el código que causa el punto muerto.