(我對這個問題有個解決方法,但這不是我第一次被咬,所以我想知道到底發生了什麼)Control.Invoke在隱藏的ShowDialog中被卡住
- 從我的申請,我
ShowDialog
的一種形式。 - 在表單上是一個按鈕,當點擊按鈕時調用另一個(非Gui)線程上的代碼。
- 非GUI線程通過發送回狀態(
Pushed
然後Released
)一個Control.Invoke - 當窗體看到
Pushed
,它調用form.Hide()
- 當窗體看到
Released
,它改變的外觀按鈕。
會發生什麼情況是,有時,但不是每次,非Gui線程都會'卡住'試圖發送Released
。沒有例外,桂繼續「工作」,但在任何方向上都不可能與非桂線進行進一步的溝通。
(簡化)調用堆棧的線程看起來是這樣的:
System.Threading.WaitHandle.WaitOne()
(...)
System.Windows.Forms.Control.WaitForWaitHandle()
(...)
System.Windows.Forms.Control.Invoke()
(...)
GuiCode.OnStatusChanged()
(...)
NonGuiCode.SetStatus()
的問題消失,如果我有Show
取代ShowDialog
,但 - 有趣的是 - 它變得更好(經常發生較少),但不如果我註釋掉Pushed
上的Hide
的代碼,則完全消失。
更新
感謝nobugz,我發現死鎖(我只見過它在數據庫之前)!顯然用Control.BeginInvoke替代Control.Invoke可以解決這個問題(狀態事件有時會「卡住」,但不會阻塞所有後續通信)。
是的,我試圖回收表單。話雖如此,關閉它,或只是設置DialogResult,仍然具有相同的效果。現在我需要去了解Invoke和BeginInvoke之間的區別... – Benjol 2010-01-13 13:12:40