У меня есть приложение WPF, которое содержит немодальную форму Win32. Все работает без сбоев, пока я не присоединю 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
), но это похоже на грязный хак.
Кто-нибудь когда-нибудь видел что-нибудь подобное?
Кто-нибудь знает, почему класс SystemEvents
будет использовать Control.Invoke
, когда сообщение поступит в основной поток (STA) (это я проверял)?
РЕДАКТИРОВАТЬ: Ответы на вопросы в комментариях:
- Происходит ли то же самое при изменении настроек дисплея (например, res) без VNC? -> Нет.
- Происходит ли то же самое с парой разных версий VNC (включая последнюю версию hte)? -> Я пробовал только последнюю версию 1.0.9.5.
- Любые другие сведения о приложении WPF, элементах управления или элементах управления Win32? -> Есть главное окно WPF и немодальная форма WinForms.