5

モードレス Win32 フォームをホストする WPF アプリケーションがあります。VNC をマシンに接続または接続解除するまで、すべてがスムーズに実行されます。その後、アプリケーションはデッドロックします。これ以上何も再描画せず、ユーザーの操作に反応しません。WinDbg を使用してスタック トレースを確認しました。

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 のアタッチ/デタッチがOnDisplaySettingsChangingイベントを発生させ、次に を使用して何らかのイベントを呼び出そうとSystem.Windows.Forms.Control.Invokeし、メイン スレッドにメッセージを送信してから応答を待ちます。しかし、これはすべてメイン スレッドで行われるため、メッセージ ループはメッセージを取得せず、待機は戻りません。

EnableSystemEventsThreadAffinityCompatibility(本質的に呼び出しをバイパスする)を使用して回避策を見つけましたControl.Invokeが、それは汚いハックのように感じます。

誰かがこのようなことが起こるのを見たことがありますか?

メッセージがメイン(STA)スレッドに到着したときにSystemEventsクラスが使用する理由を誰かが知っていますか(チェックしました)?Control.Invoke

編集:コメント内の質問への回答:

  • VNC を使用せずに表示設定 (例: res) を変更すると、同じことが起こりますか? ->いいえ。
  • VNC のいくつかの異なるバージョン (最新のものを含む) でも同じことが起こりますか? -> 最新バージョン 1.0.9.5 しか試していません。
  • WPF アプリ、コントロール、または Win32 コントロールに関するその他の詳細はありますか? -> WPF メイン ウィンドウとモードレスの WinForms フォームがあります。
4

1 に答える 1

1

これはプログラムの初期化の問題です。カスタム スプラッシュ スクリーンに注意してください。最初のイベント サブスクリプションがメイン スレッドで発生しない場合、間違ったスレッドで通知が発生します。これは、奇妙なペイント アーティファクトから完全なデッドロックに至るまで、あらゆる種類の厄介な問題を引き起こす可能性があります。いくつかの標準の Winforms コントロールは SystemEvents を使用して、Windows テーマまたはシステム カラーが変更されたときに再描画する必要があることを認識していることに注意してください。

回避策の 1 つは、他の処理を行う前に、Main() メソッドでダミーのイベント ハンドラーを明示的にサブスクライブすることです。

于 2011-07-14T18:38:17.170 に答える