Что такое насос сообщений?

В этот поток (опубликовано около года назад) есть обсуждение проблем, которые могут возникнуть при запуске Word в неинтерактивном сессия. Совет (достаточно сильный), который дается там, не должен делать этого. В одном сообщении говорится: "Все API-интерфейсы Office предполагают, что вы используете Office в интерактивном сеансе на рабочем столе, с монитором, клавиатурой и мышью и, что самое важное, с насосом сообщений". Я не уверен, что это. (Я программировал на С# только около года, другой опыт программирования был в основном с ColdFusion.)

Обновление:

Моя программа проходит через большое количество файлов RTF, чтобы извлечь две части информации, используемые для создания номера медицинского отчета. Вместо того, чтобы пытаться выяснить, как работают инструкции по форматированию в RTF, я решил просто открыть их в Word и вытащить текст оттуда (без фактического запуска GUI). Иногда программа икнулась в середине обработки одного файла и оставила поток Word открытым, прикрепленным к этому документу (мне все равно нужно выяснить, как его закрыть). Когда я повторно запускал программу, конечно, я получил уведомление о том, что был поток с этим файлом, и я хотел открыть копию только для чтения? Когда я сказал "Да", графический интерфейс Word неожиданно появился из ниоткуда и начал обрабатывать файлы. Мне было интересно, почему это произошло; но похоже, что, возможно, после того, как в диалоговом окне появится сообщение, насос начал также нажимать основной графический интерфейс на Windows?

Ответ 1

Цикл сообщений - это небольшой фрагмент кода, который существует в любой родной программе Windows. Он примерно выглядит следующим образом:

MSG msg;
while(GetMessage(&msg, NULL, 0, 0))
{ 
   TranslateMessage(&msg); 
   DispatchMessage(&msg); 
} 

API GetMessage() Win32 извлекает сообщение из Windows. Ваша программа обычно тратит 99,99% своего времени, ожидая, пока Windows сообщит, что произошло что-то интересное. TranslateMessage() - вспомогательная функция, которая преобразует сообщения клавиатуры. DispatchMessage() гарантирует, что оконная процедура вызывается с сообщением.

Каждая программа с включенным графическим интерфейсом .NET имеет цикл сообщений, она запускается Application.Run().

Актуальность цикла сообщений для Office связана с COM. Офисные программы - это программы с поддержкой COM, как работают классы Microsoft.Office.Interop. COM заботится о потоковом потоке от имени COM-класса, он гарантирует, что вызовы, выполняемые на COM-интерфейсе, всегда выполняются из правильной нити. Большинство COM-классов имеют раздел реестра в реестре, который объявляет их ThreadingModel, но наиболее распространенными из них (включая Office) пользуются "Apartment". Это означает, что единственным безопасным способом вызова метода интерфейса является вызов из того же потока, который создал объект класса. Или иначе: большинство COM-классов не являются потокобезопасными.

Каждый поток, поддерживаемый COM, принадлежит COM-квартире. Есть два вида: одноремонтные квартиры (STA) и многоволоконная квартира (MTA). Профилируемый COM-класс должен быть создан в потоке STA. Вы можете увидеть это снова в программах .NET, точка входа в поток пользовательского интерфейса программы Windows Forms или WPF имеет атрибут [STAThread]. Модель квартиры для других потоков задается методом Thread.SetApartmentState().

Большие части сантехники Windows не будут работать правильно, если поток пользовательского интерфейса не является STA. В частности, Drag + Drop, буфер обмена, диалоговые окна Windows, такие как OpenFileDialog. И любой элемент управления ActiveX и большинство COM-серверов, например Office.

Жесткая потребность в потоке STA заключается в том, что он никогда не должен блокировать и должен накапливать контур сообщения. Цикл сообщений важен, потому что то, что использует COM для маршалирования вызова метода интерфейса из одного потока в другой. Хотя .NET упрощает маршалинг-вызовы (например, Control.BeginInvoke или Dispatcher.BeginInvoke), на самом деле это очень сложно. Поток, который выполняет вызов, должен находиться в хорошо известном состоянии. Вы не можете просто произвольно прервать поток и заставить его сделать вызов метода, что вызовет ужасные проблемы с повторным подключением. Поток должен быть "бездействующим", а не занятым, выполняющим какой-либо код, который изменяет состояние программы.

Возможно, вы можете видеть, где это ведет: да, когда программа выполняет цикл сообщений, она неактивна. Фактическое маршалинг происходит через скрытое окно, созданное COM, оно использует PostMessage, чтобы оконная процедура этого окна выполняла код. В потоке STA. Цикл сообщения обеспечивает выполнение этого кода.

Ответ 2

"Message pump" - это основная часть любой программы Windows, которая отвечает за отправку оконных сообщений в различные части приложения. Это ядро ​​программирования Win32 UI. Из-за своей повсеместности многие приложения используют насос сообщений для передачи сообщений между различными модулями, поэтому приложения Office будут разбиты, если они будут запущены без какого-либо интерфейса.

В Википедии есть базовое описание.

Ответ 3

Джон говорит о том, как система Windows (и другие системы на основе окон - X Window, оригинальная Mac OS....) реализуют асинхронные пользовательские интерфейсы с использованием событий через систему сообщений.

За кулисами для каждого приложения есть система обмена сообщениями, в которой каждое окно может отправлять события другим окнам или прослушивателям событий - это реализовано добавлением сообщения в очередь сообщений. Существует основной цикл, который всегда запускает просмотр этой очереди сообщений, а затем отправляет сообщения (или события) слушателям.

Статья в Википедии Цикл сообщений в Microsoft Windows показывает пример кода базовой программы Windows - и, как вы можете видеть на самой простой уровень программы Windows - это просто "насос сообщений".

Итак, чтобы собрать все это вместе. Причина, по которой программа Windows, разработанная для поддержки пользовательского интерфейса, не может действовать как услуга, потому что для включения поддержки пользовательского интерфейса все время требуется цикл сообщений. Если вы реализуете его как сервис, как описано, он не сможет обработать внутреннюю обработку асинхронных событий.

Ответ 4

В COM, передача сообщений сериализует и десеризует сообщения, отправленные между квартирами. Квартира представляет собой мини-процесс, в котором могут работать COM-компоненты. Апартаменты оснащены однопоточными и свободными резьбовыми модулями. Однопоточные квартиры в основном представляют собой устаревшую систему для приложений COM-компонентов, которые не поддерживают многопоточность. Они обычно использовались с Visual BASIC (поскольку это не поддерживало многопоточный код) и устаревшие приложения.

Я полагаю, что требование сообщения о сообщении для Word связано либо с COM API, либо с частями приложения, которые не являются потокобезопасными. Имейте в виду, что модели .NET нитей и мусора не прекрасно сочетаются с COM из коробки. COM имеет очень упрощенный механизм сбора мусора и модель потоковой передачи, которая требует, чтобы вы делали что-то в режиме COM. Использование стандартного Office PIA по-прежнему требует, чтобы вы явно закрывали ссылки на COM-объекты, поэтому вам нужно отслеживать каждый созданный COM-дескриптор. PIAs также создадут материал за кулисами, если вы не будете осторожны.

Интеграция с .NET-COM - это целая тема сама по себе, и есть даже книги, написанные на эту тему. Даже используя COM API для Office из интерактивного настольного приложения, вы должны перепрыгнуть через обручи и убедиться, что ссылки явно выпущены.

Office можно считать небезопасным, поэтому вам понадобится отдельный экземпляр Word, Excel или другой Office для каждого потока. Вам придется понести стартовые накладные расходы или поддерживать пул потоков. Пул потоков должен быть подвергнут тщательной проверке, чтобы убедиться, что все COM-ссылки были правильно выпущены. Даже запуск и закрытие экземпляров требует, чтобы все ссылки были правильно выпущены. Неспособность расслоить ваш я и пересечь ваш т здесь приведет к большому количеству мертвых COM-объектов и даже целых запущенных экземпляров Word, которые просочились.

Ответ 6

Я думаю, что этот диалог 9-го канала имеет приятное краткое объяснение:

Этот процесс оконной коммуникации становится возможным благодаря так называемому Windows Message Pump. Подумайте о том, что Message Pump является объектом, который позволяет взаимодействовать между окнами приложений и рабочим столом.