(この問題の回避策はありますが、噛まれたのは初めてではないので、何が起こっているのかを正確に理解しようとしています。)
- 私のアプリケーションから、私
ShowDialogはフォームです。 - フォームにはボタンがあり、クリックすると別の(GUI以外の)スレッドのコードが呼び出されます。
Pushed非GUIスレッドはReleased、Control.Invokeを介してステータス(および)を送り返します。- フォームがを見ると
Pushed、を呼び出しますform.Hide() - フォーム
Releasedにが表示されると、ボタンの外観が変わります。
何が起こるかというと、常にではありませんが、Gui以外のスレッドがを送信しようとして「スタック」することがありReleasedます。例外はありませんが、Guiは「作業」を続行しますが、どちらの方向でも、非Guiスレッドとのそれ以上の通信はできません。
スレッドの(簡略化された)コールスタックは次のようになります。
System.Threading.WaitHandle.WaitOne()
(...)
System.Windows.Forms.Control.WaitForWaitHandle()
(...)
System.Windows.Forms.Control.Invoke()
(...)
GuiCode.OnStatusChanged()
(...)
NonGuiCode.SetStatus()
に置き換えるShowDialogと問題は解決しますが、興味深いことに、問題は改善されます(発生頻度は低くなります)が、 onShowを実行するコードをコメントアウトしても完全には解決しません。HidePushed
アップデート
nobugzのおかげで、デッドロックを発見しました(これまでデータベースでしか遭遇していませんでした)。どうやらControl.InvokeをControl.BeginInvokeに置き換えると、この問題は解決します(ステータスイベントは「スタック」することがありますが、後続のすべての通信をブロックするわけではありません)。