(У меня есть обходной путь для этой проблемы, но я не первый раз укушен, поэтому я пытаюсь точно понять, что происходит.)
- Из моего заявления я
ShowDialog
форма.
- На форме есть кнопка, которая при нажатии вызывает код в другом (не-Gui) потоке.
- Поток без графического интерфейса отправляет назад статусы (
Pushed
затем 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
на Show
, но - что интересно - она станет лучше (случается реже), но не исчезнет полностью, если я закомментирую код, который выполняет Hide
Pushed
.
Обновление
Благодаря nobugz я обнаружил тупик (раньше я встречал его только в базах данных)! Очевидно, замена Control.Invoke на Control.BeginInvoke решает эту проблему (событие состояния все еще иногда «застревает», но не блокирует все последующие сообщения).