6

GUI スレッドでロックしているアプリケーションがあり、WinDbg と "!clrstack" コマンドを使用してこのスタック トレースを取得しましたが、問題の場所がわかりません。これらのメソッドはすべてフレームワーク メソッドのように見えますが、私のものはありません。どんな助けでも大歓迎です。長文失礼します

OS Thread Id: 0x724 (0)
ESP       EIP     
0012ec88 7c90e4f4 [HelperMethodFrame_1OBJ: 0012ec88] System.Threading.WaitHandle.WaitOneNative(Microsoft.Win32.SafeHandles.SafeWaitHandle, UInt32, Boolean, Boolean)
0012ed34 792b687f System.Threading.WaitHandle.WaitOne(Int64, Boolean)
0012ed50 792b6835 System.Threading.WaitHandle.WaitOne(Int32, Boolean)
0012ed64 7b6f192f System.Windows.Forms.Control.WaitForWaitHandle(System.Threading.WaitHandle)
0012ed78 7ba2d0bb System.Windows.Forms.Control.MarshaledInvoke(System.Windows.Forms.Control, System.Delegate, System.Object[], Boolean)
0012ee18 7b6f328c System.Windows.Forms.Control.Invoke(System.Delegate, System.Object[])
0012ee4c 7b920717 System.Windows.Forms.WindowsFormsSynchronizationContext.Send(System.Threading.SendOrPostCallback, System.Object)
0012ee64 7a924102 Microsoft.Win32.SystemEvents+SystemEventInvokeInfo.Invoke(Boolean, System.Object[])
0012ee98 7a922833 Microsoft.Win32.SystemEvents.RaiseEvent(Boolean, System.Object, System.Object[])
0012eee4 7a923d2f Microsoft.Win32.SystemEvents.OnUserPreferenceChanged(Int32, IntPtr, IntPtr)
0012ef04 7aa8f184 Microsoft.Win32.SystemEvents.WindowProc(IntPtr, Int32, IntPtr, IntPtr)
0012ef08 003620a4 [InlinedCallFrame: 0012ef08] 
0012f0cc 7b1d8cce System.Windows.Forms.Application+ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32, Int32, Int32)
0012f168 7b1d8937 System.Windows.Forms.Application+ThreadContext.RunMessageLoopInner(Int32, System.Windows.Forms.ApplicationContext)
0012f1bc 7b1d8781 System.Windows.Forms.Application+ThreadContext.RunMessageLoop(Int32, System.Windows.Forms.ApplicationContext)
0012f1ec 7b195911 System.Windows.Forms.Application.Run(System.Windows.Forms.Form)
0012f200 00eb0ebb WinForms1.Program.Main()
0012f69c 79e71b4c [GCFrame: 0012f69c] 
4

4 に答える 4

8

このコードが問題の本当の原因ではないようです。これらのページのいずれかが役立つかどうかを確認してください。

更新:最初のページのURLを修正しました。

于 2009-02-17T23:53:33.690 に答える
3

他の答えはこのアーロン・ラーチから来ています。私は「他の誰かのコードでフィルタリングされたブレークポイント」の部分が本当に好きです。数日節約できたと思います。

http://www.aaronlerch.com/blog/2008/12/15/debugging-ui/

于 2009-05-01T15:02:00.617 に答える
1

同様の問題があり、コードに原因が見つかりました。

使用されたテクニック: 0. Spy++ で、コントロールを持つアンマネージ スレッドが 2 つしかないことを確認します (WinForms と GDI+):

public static class ThreadingHelper_NativeMethods
{
   [DllImport("user32.dll")]
   public static extern bool IsGUIThread(bool bConvert);
}

初期化時に UI スレッドからこれを呼び出します。

// This code forces initialization of .NET BroadcastEventWindow to the UI thread.
// http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/fb267827-1765-4bd9-ae2f-0abbd5a2ae22
if (ThreadingHelper_NativeMethods.IsGUIThread(false))
{
    Microsoft.Win32.SystemEvents.InvokeOnEventsThread(new MethodInvoker(delegate()
    {
    int x = 0;
    }));
}
  1. シングルトン クラスの Ui スレッドのマネージド ID を記憶します。

  2. コードで定義されているすべての UserControls を検索します。各コントロールのコンストラクターで、InitializeComponent() を呼び出す前に、メイン スレッド ID に対して現在のスレッド ID をチェックするコードを配置しました。等しくない場合は、Assert(false) を返します。

  3. SystemEvents.UserPreferencesChanging にサブスクライブします。ハンドラーの Debug.Assert(false): これは SystemEvents.UserPreferencesChanged の前に発生するため、デバッガーはここで一時停止します。

  4. デバッガーで SystemEvents へのサブスクライバーのリストを調べます。リストの _handles ディクショナリで購読者を見つけます。各コールバックの SynchronizationContext を開くと、問題が明らかになるはずです。非 UI スレッドで作成されたコントロールと同じスレッド ID です。SystemEvents はそのスレッドでイベント ハンドラーを実行し、UI スレッドに対してデッドロックします。

于 2009-04-28T16:27:47.940 に答える
0

この回答の関数 CheckSystemEventsHandlersForFreeze() は、GUI スレッドがロックされる根本原因を見つけるのに役立ちます。

于 2018-10-11T08:58:31.600 に答える