我们偶尔会出现这样的情况,即应用程序已经死锁,而且调度程序似乎已经陷入僵局,后台线程试图在调度程序上调用。我没有看到任何一个线程都有任何被锁定的共享资源。后台线程遇到异常,它最终在app域未处理的异常委托中,因为没有人拿起这个异常。这将调用我们的异常处理程序,其任务是确保将异常对话框放入调度程序。
有人可以提出一些方法可以找出导致死锁的原因吗?
调度程序堆栈跟随并且看起来不同寻常:
*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)
第二个线程堆栈从app域未处理的异常处理程序中基本启动:
*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)
似乎Invoke正在按预期等待,但似乎调度程序线程本身也被阻止。在这些情况下我们等了很多分钟,应用程序永远不会回来。任何帮助或见解将不胜感激。我知道我可以切换到BeginInvoke但是基于这里的上下文我担心我的后台线程会继续,并且UI会因为同样的原因被阻止,或者不会出现异常对话框。
当异常显示在域未处理的异常处理程序时,我们的后台线程执行以下代码流:
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);
}
}
答案 0 :(得分:1)
而不是control.Dispatcher.Invoke
尝试control.Dispatcher.BeginInvoke
,这在以前的角落里帮助了我。
另外,你的代码对我来说有点奇怪。在我的应用中,我在主窗口AppDomain.CurrentDomain.UnhandledException
事件中设置了Loaded()
事件处理程序。该事件附加到主窗口的本地方法。因此,我不需要执行任何Dispatcher调用,因为事件已经在主调度程序线程上引发,即使错误确实发生在另一个线程上。