Синхронизация вызовов
COM-приложения должны иметь возможность правильно работать с входными данными пользователя при обработке одного или нескольких вызовов из COM или операционной системы. COM обеспечивает синхронизацию вызовов только для однопоточных квартир. Многопоточные квартиры (содержащие свободные потоки) не получают вызовы при выполнении вызовов (в одном потоке). Многопоточные квартиры не могут выполнять синхронизированные вызовы ввода. Асинхронные вызовы преобразуются в синхронные вызовы в многопоточных квартирах. Фильтр сообщений не вызывается для потока в многопоточной квартире. Дополнительные сведения о проблемах с потоком см. в разделе "Процессы", "Потоки" и "Квартиры".
Вызовы COM между процессами делятся на три категории, как показано ниже.
-
Синхронные вызовы
-
Большая часть сообщений, происходящих в COM, синхронна. При выполнении синхронных вызовов вызывающий объект ожидает ответа перед продолжением и может получать входящие сообщения во время ожидания. COM входит в модальный цикл для ожидания ответа, получения и отправки других сообщений управляемым образом.
-
Асинхронные уведомления
-
При отправке асинхронных уведомлений вызывающий объект не ожидает ответа. COM использует PostMessage или высокоуровневые события для отправки асинхронных уведомлений в зависимости от платформы. COM определяет пять асинхронных методов IAdviseSink:
Примечание
Хотя COM обрабатывает асинхронный вызов, синхронные вызовы невозможно выполнить. Например, реализация приложения контейнера OnDataChange не может содержать вызов IPersistStorage::Save. Эти вызовы являются единственными асинхронными вызовами, поддерживаемыми COM. В настоящее время невозможно создать пользовательский интерфейс, который является асинхронным.
-
Вызовы, синхронизированные входными данными
-
При вызове синхронизированных входных данных вызываемый объект должен завершить вызов перед получением элемента управления. Это помогает обеспечить правильную работу управления фокусом и правильность обработки данных, введенных пользователем. Эти вызовы выполняются COM через функцию SendMessage без ввода модального цикла. При обработке синхронизированного вызова, вызываемый объект не должен вызывать какие-либо функции или методы (включая синхронные методы), которые могут привести к управлению. Следующие методы синхронизированы вводимыми данными.
- IOleWindow::GetWindow
- IOleInPlaceActiveObject::OnFrameWindowActivate
- IOleInPlaceActiveObject::OnDocWindowActivate
- IOleInPlaceActiveObject::ResizeBorder
- IOleInPlaceUIWindow::GetBorder
- IOleInPlaceUIWindow::RequestBorderSpace
- IOleInPlaceUIWindow::SetBorderSpace
- IOleInPlaceFrame::SetMenu
- IOleInPlaceFrame::SetStatusText
- IOleInPlaceObject::SetObjectRects
Чтобы свести к минимуму проблемы, которые могут возникнуть из-за асинхронной обработки сообщений, большинство вызовов метода COM синхронны. При синхронном обмене данными нет необходимости в специальном коде для отправки и обработки входящих сообщений. Когда приложение вызывает синхронный метод, COM входит в модальный цикл ожидания, который обрабатывает необходимые ответы и отправляет входящие сообщения приложениям, способным их обрабатывать.
COM управляет вызовами методов путем назначения идентификатора, называемого идентификатором логического потока. Новый назначается, когда пользователь выбирает команду меню или когда приложение инициирует новую com-операцию. Последующие вызовы, относящиеся к первоначальному вызову COM, назначаются тем же идентификатором логического потока, что и начальный вызов.