2012-02-14 18 views
13

アプリケーションがデッドロックされ、ディスパッチャがデッドロックされ、ディスパッチャで起動しようとしているバックグラウンドスレッドがデッドロックしているように見えることがあります。どちらのスレッドにもロックされている共有リソースがないことはわかりません。バックグラウンドスレッドで例外が発生しましたが、誰もこの例外を選択しなかったため、アプリケーションドメインの未処理の例外デリゲートで終了します。これは、私たちの例外ダイアログがディスパッチャに置かれることを保証することを任された例外ハンドラを呼び出します。ディスパッチャを呼び出すときにWPFアプリケーションがデッドロックされる

デッドロックの原因を突き止める方法を提案する人はいますか?

ディスパッチャスタックは、次のと普通の外には見えません。

*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) 

第二のスレッドがスタックは、アプリケーションドメイン未処理の例外ハンドラからbascically始まり:

*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

コードを投稿できますか? – Rachel

+0

私は、アプリドメイン未処理の例外ハンドラから実行するコードを投稿しました。 – Ben

+0

デッドロックがアクティブな間にUIスレッドのスタックトレースを確認する方が面白いでしょう。 UIスレッドはおそらく何かを待っているので、ディスパッチャはブロックされます。次にデッドロックが発生したときにデバッガをブレークし、UIスレッドのスタックトレースを確認します。あなたのUIスレッドがThread.Join(または同様のもの)の中にあり、バックグラウンドスレッドがディスパッチャを呼び出そうとしている可能性はありますか?私はデッドロックのために長い時間前にInvokeを使用して停止しました。BeginInvokeだけです。 – stmax

答えて

1

代わりのcontrol.Dispatcher.Invokeは、このようなコーナーケースに前に私を助けているcontrol.Dispatcher.BeginInvokeを、してみてください。

また、あなたのコードは少し奇妙なようです。私のアプリでは、AppDomain.CurrentDomain.UnhandledExceptionイベントハンドラをメインウィンドウLoaded()イベントに設定しました。このイベントは、メインウィンドウのローカルメソッドにアタッチされます。したがって、別のスレッドでエラーが発生したとしても、ディスパッチャーの主スレッドでイベントが発生しているため、Dispatcherを呼び出す必要はありません。

+0

'Invoke'から' BeginInvoke'に切り替えることは必ずしも可能ではありません。前者は同期、後者は非同期です。呼び出し先が呼び出された呼び出しの影響に依存する場合、それは簡単かもしれません。 –

関連する問題