(この問題の回避策はありますが、噛まれたのは初めてではないので、何が起こっているのかを正確に理解しようとしています。)
- 私のアプリケーションから、私
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
を実行するコードをコメントアウトしても完全には解決しません。Hide
Pushed
アップデート
nobugzのおかげで、デッドロックを発見しました(これまでデータベースでしか遭遇していませんでした)。どうやらControl.InvokeをControl.BeginInvokeに置き換えると、この問題は解決します(ステータスイベントは「スタック」することがありますが、後続のすべての通信をブロックするわけではありません)。