私は、モードレスWin32フォームをホストするWPFアプリケーションを持っています。 VNCをマシンに接続するか取り外すまで、すべてがスムーズに実行されます。その後、アプリケーションはデッドロックします。何も再描画されず、ユーザーの操作に反応しません。私はWinDbgのを使用して、スタックトレースを見てきました:DisplaySettingsChangingのWPF interopデッドロック
0012f03c 792b6865 System.Threading.WaitHandle.WaitOne(Int32, Boolean)
0012f050 7b6f1a4f System.Windows.Forms.Control.WaitForWaitHandle(System.Threading.WaitHandle)
0012f064 7ba2d68b System.Windows.Forms.Control.MarshaledInvoke(System.Windows.Forms.Control, System.Delegate, System.Object[], Boolean)
0012f104 7b6f33ac System.Windows.Forms.Control.Invoke(System.Delegate, System.Object[])
0012f138 7b920bd7 System.Windows.Forms.WindowsFormsSynchronizationContext.Send(System.Threading.SendOrPostCallback, System.Object)
0012f150 7a92ed62 Microsoft.Win32.SystemEvents+SystemEventInvokeInfo.Invoke(Boolean, System.Object[])
0012f184 7a92dc8f Microsoft.Win32.SystemEvents.RaiseEvent(Boolean, System.Object, System.Object[])
0012f1d0 7a92daec Microsoft.Win32.SystemEvents.OnDisplaySettingsChanging()
0012f1e0 7a574c9f Microsoft.Win32.SystemEvents.WindowProc(IntPtr, Int32, IntPtr, IntPtr)
0012f1e4 003c20dc [InlinedCallFrame: 0012f1e4]
0012f3a8 57843a57 System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame)
0012f3f8 57843129 System.Windows.Threading.Dispatcher.PushFrame(System.Windows.Threading.DispatcherFrame)
0012f404 578430cc System.Windows.Threading.Dispatcher.Run()
0012f410 55bed46e System.Windows.Application.RunDispatcher(System.Object)
0012f41c 55bec76f System.Windows.Application.RunInternal(System.Windows.Window)
0012f440 55bd3aa6 System.Windows.Application.Run(System.Windows.Window)
0012f450 55bd3a69 System.Windows.Application.Run()
どうやら、VNCは/デタッチが順番にメインスレッドにメッセージを送信し、System.Windows.Forms.Control.Invoke
を使用して、いくつかのイベントを呼び出そうとしOnDisplaySettingsChanging
イベントを発生させ添付する応答を待ちます。しかし、これはすべてメインスレッドで発生するため、メッセージループは決してメッセージを取得せず、待機は返されません。
EnableSystemEventsThreadAffinityCompatibility
(これは本質的にControl.Invoke
呼び出しをバイパスします)を使用して回避策を見つけましたが、汚れたハックのように感じます。
このようなことが起こったことはありますか?
SystemEvents
クラスは、メッセージがメイン(STA)スレッドに到着したときにControl.Invoke
を使用する理由を知りましたか?
編集:コメント欄での質問への回答:VNCせずにディスプレイの設定(例えば、解像度)を変更するとき
- 同じことが起こるのでしょうか? - > No.
- VNCで複数の異なるバージョン(hte最新版を含む)でも同じことが起こりますか? - >私は最新のバージョン1.0.9.5を試してみました。
- WPFアプリ、コントロール、またはWin32コントロールに関するその他の詳細は? - > WPFのメインウィンドウとモードレスのWinFormsフォームがあります。
いくつかのQ: '1 'VNCを使わずにディスプレイ設定(resなど)を変更しても同じことが起こりますか? '2)' VNC上のいくつかの異なるバージョン(hte最新版を含む)でも同じことが起こりますか? '3)' WPFアプリケーション、コントロール、またはWin32コントロールについてのその他の詳細は? –
これはプログラムの初期化の問題です。カスタムスプラッシュ画面に注意してください。 –
@Hans Passant:ありがとう!私は 'ISynchronizeInvoke'が必要なので起動時に' Form'を作成しました。これが問題の原因でした。私はそれを 'Control'に変更しました。そして、すべてがスムーズに機能します。私はそれを受け入れることができるように、あなたのコメントを回答として投稿してください。 – Niki