Есть ПО для которого пишется расширение(COM). Дёргать API этого ПО можно только из его потока(если поток придержать, то ПО повисает и не отвечает), то есть потока который он выделил при загрузки расширения. Так же осуществляется связь этого расширения по средствам WCF со сторонней программой.
На текущий момент сделаны костыли в виде WinForms invoke():
В Parent Thread создаётся Form, а из WCF Thread дёргается его Invoke().
Как я понимаю Invoke отправляет сообщение в пул сообщений главного цикла WinForms, а тот в свою очередь дёргает соответствующую функцию. Только не понятно каким образом WinForms прописывается в главный цикл обработки сообщений ПО?
Здравствуйте, v_0ver, Вы писали:
_>Есть ПО для которого пишется расширение(COM). Дёргать API этого ПО можно только из его потока(если поток придержать, то ПО повисает и не отвечает), то есть потока который он выделил при загрузки расширения. Так же осуществляется связь этого расширения по средствам WCF со сторонней программой. _>На текущий момент сделаны костыли в виде WinForms invoke(): _>Image: vhuiwl.png _>В Parent Thread создаётся Form, а из WCF Thread дёргается его Invoke().
_>Как я понимаю Invoke отправляет сообщение в пул сообщений главного цикла WinForms, а тот в свою очередь дёргает соответствующую функцию. Только не понятно каким образом WinForms прописывается в главный цикл обработки сообщений ПО?
Если речь про Control.Invoke- то в конце концов зовется
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern bool PostMessage(HandleRef hwnd, int msg, IntPtr wparam, IntPtr lparam);
Это легко установить при помощи любого дизассемблера
Шурыгин Сергей
"Не следует преумножать сущности сверх необходимости" (с) Оккам
Здравствуйте, Sshur, Вы писали:
S>Здравствуйте, v_0ver, Вы писали:
_>>Есть ПО для которого пишется расширение(COM). Дёргать API этого ПО можно только из его потока(если поток придержать, то ПО повисает и не отвечает), то есть потока который он выделил при загрузки расширения. Так же осуществляется связь этого расширения по средствам WCF со сторонней программой. _>>На текущий момент сделаны костыли в виде WinForms invoke(): _>>Image: vhuiwl.png _>>В Parent Thread создаётся Form, а из WCF Thread дёргается его Invoke().
_>>Как я понимаю Invoke отправляет сообщение в пул сообщений главного цикла WinForms, а тот в свою очередь дёргает соответствующую функцию. Только не понятно каким образом WinForms прописывается в главный цикл обработки сообщений ПО?
S>Если речь про Control.Invoke- то в конце концов зовется
S>[DllImport("user32.dll", CharSet = CharSet.Auto)] S>public static extern bool PostMessage(HandleRef hwnd, int msg, IntPtr wparam, IntPtr lparam);
S>Это легко установить при помощи любого дизассемблера
Это понятно, что вызывается PostMessage(), меня интересует каким образом уживаются 2 цикла обработки сообщений в одной нити.
Здравствуйте, v_0ver, Вы писали:
_>Это понятно, что вызывается PostMessage(), меня интересует каким образом уживаются 2 цикла обработки сообщений в одной нити.
В общую, единственную, очередь сообщений потока добавляется кастомное сообщение "..._ThreadCallbackMessage". В коде обработки из сообщения достается коллбек и вызывается. Вот и все.
Здравствуйте, catbert, Вы писали:
C>Здравствуйте, v_0ver, Вы писали:
_>>Это понятно, что вызывается PostMessage(), меня интересует каким образом уживаются 2 цикла обработки сообщений в одной нити.
C>В общую, единственную, очередь сообщений потока добавляется кастомное сообщение "..._ThreadCallbackMessage". В коде обработки из сообщения достается коллбек и вызывается. Вот и все.
В коде обработки оно "руками" обрабатывается или это происходит прозрачно?
If the target window belongs to a different thread from the caller, then the callback function is called only when the thread that called SendMessageCallback also calls GetMessage, PeekMessage, or WaitMessage.
Из чего следует, что вызвать калбек из потока отличного потоку обработчика сообщений нельзя?
Создается и добавляется в обычную .NET-очередь некий ThreadMethodEntry (TME), который содержит обычный .NET-делегат, вейт-сигнал и какой-то контекст.
Если мы в UI-потоке, просто выполняем все TME из очереди.
Иначе, мы вызываем WinAPI-шный PostMessage с кастомным сообщением WindowsForms12_ThreadCallbackMessage, вообще без каких-либо параметров.
В случае синхронного вызова (Invoke), мы ждем вейт-сигнал из TME, созданного в шаге 1.
Сообщения обрабатываются в методе Control.WndProc:
Здравствуйте, v_0ver, Вы писали:
_>Как я понимаю Invoke отправляет сообщение в пул сообщений главного цикла WinForms, а тот в свою очередь дёргает соответствующую функцию. Только не понятно каким образом WinForms прописывается в главный цикл обработки сообщений ПО?
Сообщение в Control.Invoke отправляется окну — а кто реализует цикл выборки сообщений не суть важно.
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Здравствуйте, v_0ver, Вы писали:
_>Как я понимаю Invoke отправляет сообщение в пул сообщений главного цикла WinForms, а тот в свою очередь дёргает соответствующую функцию. Только не понятно каким образом WinForms прописывается в главный цикл обработки сообщений ПО?
PostMessage, PostThreadMessage, например. Главный цикл реализуется внутри WinForms и знает, как все обрабатывать.