Ocasionalmente, tenemos una situación en la que la aplicación está en punto muerto y parece que el despachador está bloqueado con una cadena de fondo que intenta invocar en el despachador. No veo que ninguno de los hilos tenga recursos compartidos que estén bloqueados. El hilo de fondo ha encontrado una excepción y termina en el delegado de excepción no controlada del dominio de la aplicación porque nadie recogió esta excepción. Esto llama a nuestro controlador de excepción que tiene la tarea de asegurar que nuestro diálogo de excepción se ponga en el despachador.La aplicación WPF está bloqueada al invocar en el Dispatcher
¿Alguien puede sugerir formas en que puedo descubrir qué está causando el punto muerto?
La pila despachador sigue y no se ve fuera de lo común:
*0. System.Windows.Threading.DispatcherSynchronizationContext.Wait (source line information unavailable)
1. System.Threading.SynchronizationContext.InvokeWaitMethodHelper (source line information unavailable)
2. Xceed.Wpf.DataGrid.DeferredOperationManager.Process (source line information unavailable)
3. Xceed.Wpf.DataGrid.DeferredOperationManager.Dispatched_Process (source line information unavailable)
4. System.Windows.Threading.ExceptionWrapper.InternalRealCall (source line information unavailable)
5. System.Windows.Threading.ExceptionWrapper.TryCatchWhen (source line information unavailable)
6. System.Windows.Threading.Dispatcher.WrappedInvoke (source line information unavailable)
7. System.Windows.Threading.DispatcherOperation.InvokeImpl (source line information unavailable)
8. System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext (source line information unavailable)
9. System.Threading.ExecutionContext.runTryCode (source line information unavailable)
10. System.Threading.ExecutionContext.RunInternal (source line information unavailable)
11. System.Threading.ExecutionContext.Run (source line information unavailable)
12. System.Windows.Threading.DispatcherOperation.Invoke (source line information unavailable)
13. System.Windows.Threading.Dispatcher.ProcessQueue (source line information unavailable
14. System.Windows.Threading.Dispatcher.WndProcHook (source line information unavailable)
15. MS.Win32.HwndWrapper.WndProc (source line information unavailable)
16. MS.Win32.HwndSubclass.DispatcherCallbackOperation (source line information unavailable)
17. System.Windows.Threading.ExceptionWrapper.InternalRealCall (source line information unavailable)
18. System.Windows.Threading.ExceptionWrapper.TryCatchWhen (source line information unavailable)
19. System.Windows.Threading.Dispatcher.WrappedInvoke (source line information unavailable)
20. System.Windows.Threading.Dispatcher.InvokeImpl (source line information unavailable)
21. System.Windows.Threading.Dispatcher.Invoke (source line information unavailable)
22. MS.Win32.HwndSubclass.SubclassWndProc (source line information unavailable)
[Internal Frame, 'M-->U']
23. System.Windows.Threading.Dispatcher.PushFrameImpl (source line information unavailable)
24. System.Windows.Threading.Dispatcher.PushFrame (source line information unavailable)
25. System.Windows.Threading.Dispatcher.Run (source line information unavailable)
26. System.Windows.Application.RunDispatcher (source line information unavailable)
27. System.Windows.Application.RunInternal (source line information unavailable)
28. System.Windows.Application.Run (source line information unavailable)
29. System.Windows.Application.Run (source line information unavailable)
30. Wmc.Gtseq.Client.Desktop.App.Main (source line information unavailable)
Los segundos hilos pila comienza bascically del dominio de aplicación no controlada gestor de excepciones:
*0. System.Threading.WaitHandle.WaitOne (source line information unavailable)
1. System.Threading.WaitHandle.WaitOne (source line information unavailable)
2. System.Windows.Threading.DispatcherOperation+DispatcherOperationEvent.WaitOne (source line information unavailable)
3. System.Windows.Threading.DispatcherOperation.Wait (source line information unavailable)
4. System.Windows.Threading.Dispatcher.InvokeImpl (source line information unavailable)
5. System.Windows.Threading.Dispatcher.Invoke (source line information unavailable)
6. Wmc.Gtseq.Core.ForwardPort.Extensions.DispatcherExtension.InvokeIfRequired (source line information unavailable)
7. Wmc.Gtseq.Core.ForwardPort.Utilities.DispatcherHelper.InvokeOnMainThread (source line information unavailable)
8. Wmc.Gtseq.Core.ForwardPort.Handlers.ExceptionHandler.ThreadSafeDialogHandler (source line information unavailable)
9. Wmc.Gtseq.Core.ForwardPort.Handlers.ExceptionHandler.ShowErrorDialog (source line information unavailable)
10. Wmc.Gtseq.Core.ForwardPort.Handlers.ExceptionHandler.HandleException (source line information unavailable)
11. Wmc.Gtseq.Client.Desktop.App.AppDomainUnhandledException (source line information unavailable)
Parece ser que la Invoke está esperando como se esperaba pero también parece que el subproceso del asignador está bloqueado. Hemos esperado muchos minutos en estas situaciones y la aplicación nunca vuelve. Cualquier ayuda o vision sería apreciada. Sé que puedo cambiar a BeginInvoke, pero en función del contexto aquí me preocupa que mi hilo de fondo continúe y que la IU esté bloqueada por el mismo motivo o que no aparezca el diálogo de excepción.
Nuestro hilo de fondo ejecuta el siguiente flujo de código cuando la excepción se presenta en el manejador de excepción no controlada de dominio:
protected override void AppDomainUnhandledException(object sender, UnhandledExceptionEventArgs e)
{
ExceptionHandler.HandleException(e.ExceptionObject as Exception, false);
}
public static void HandleException(Exception ex, bool closeApp)
{
ThreadSafeDialogHandler((Action)delegate { ErrorDialog.ShowDialog(ex, closeApp); });
}
private static void ThreadSafeDialogHandler(Action methodCall)
{
DispatcherHelper.InvokeOnMainThread(() => { methodCall(); });
}
public static void InvokeOnMainThread(Action method)
{
Application.Current.InvokeIfRequired(method, DispatcherPriority.Normal);
}
public static void InvokeIfRequired(this DispatcherObject control, Action methodcall, DispatcherPriority priorityForCall)
{
// see if we need to Invoke call to Dispatcher thread
if (control.Dispatcher.CheckAccess())
{
methodcall();
}
else
{
control.Dispatcher.Invoke(priorityForCall, methodcall);
}
}
¿Puedes publicar tu código? – Rachel
Publiqué el código que se ejecuta a partir del controlador de excepciones de dominio no administrado de la aplicación. – Ben
Sería más interesante ver la traza de pila de la hebra de UI mientras el interbloqueo está activo. El subproceso de interfaz de usuario probablemente esté esperando algo, por lo que el despachador se bloquea. Interrumpa el depurador la próxima vez que se produzca el interbloqueo y compruebe el seguimiento de la pila del subproceso de interfaz de usuario. ¿Podría ser que su subproceso de interfaz de usuario esté en un Thread.Join (o algo similar) mientras que el subproceso de fondo intenta invocar en el despachador? Dejé de usar Invoke hace mucho tiempo debido a los bloqueos ... solo BeginInvoke. – stmax