Sincronização de chamadas
Os aplicativos COM devem ser capazes de lidar corretamente com a entrada do usuário durante o processamento de uma ou mais chamadas do COM ou do sistema operacional. O COM fornece sincronização de chamadas somente para apartamentos de thread único. Os apartamentos multithreaded (que contêm threads com thread livre) não recebem chamadas ao fazer chamadas (no mesmo thread). Os apartamentos multithreaded não podem fazer chamadas sincronizadas de entrada. As chamadas assíncronas são convertidas em chamadas síncronas em apartamentos multithread. O filtro de mensagem não é chamado para nenhum thread em um apartamento multithreaded. Para obter mais informações sobre problemas de threading, consulte Processos, Threads e Apartamentos.
As chamadas COM entre processos se enquadram em três categorias, da seguinte maneira:
-
chamadas síncronas
-
A maior parte da comunicação que ocorre dentro do COM é síncrona. Ao fazer chamadas síncronas, o chamador aguarda a resposta antes de continuar e pode receber mensagens de entrada enquanto aguarda. O COM insere um loop modal para aguardar a resposta, recebendo e expedindo outras mensagens de maneira controlada.
-
notificações assíncronas
-
Ao enviar notificações assíncronas, o chamador não aguarda a resposta. O COM usa postMessage ou eventos de alto nível para enviar notificações assíncronas, dependendo da plataforma. O COM define cinco métodos assíncronos de IAdviseSink:
- onDataChange
- doOnViewChange
- OnRename
- onSave
- OnClose
Nota
Enquanto COM está processando uma chamada assíncrona, não é possível fazer chamadas síncronas. Por exemplo, a implementação de um aplicativo de contêiner de OnDataChange não pode conter uma chamada para IPersistStorage::Save. Essas chamadas são as únicas chamadas assíncronas compatíveis com COM. Não há como criar uma interface personalizada assíncrona no momento.
-
chamadas sincronizadas por entrada
-
Ao fazer chamadas sincronizadas de entrada, o objeto chamado deve concluir a chamada antes de produzir o controle. Isso ajuda a garantir que o gerenciamento de foco funcione corretamente e que os dados inseridos pelo usuário sejam processados adequadamente. Essas chamadas são feitas por COM por meio da funçãoSendMessage, sem inserir um loop modal. Ao processar uma chamada sincronizada de entrada, o objeto chamado não deve chamar nenhuma função ou método (incluindo métodos síncronos) que possa produzir controle. Os métodos a seguir são sincronizados de entrada
- IOleWindow::GetWindow
- IOleInPlaceActiveObject::OnFrameWindowActivate
- IOleInPlaceActiveObject::OnDocWindowActivate
- IOleInPlaceActiveObject::ResizeBorder
- IOleInPlaceUIWindow::GetBorder
- IOleInPlaceUIWindow::RequestBorderSpace
- IOleInPlaceUIWindow::SetBorderSpace
- IOleInPlaceFrame::SetMenu
- IOleInPlaceFrame::SetStatusText
- IOleInPlaceObject::SetObjectRects
Para minimizar problemas que podem surgir do processamento de mensagens assíncronas, a maioria das chamadas de método COM são síncronas. Com a comunicação síncrona, não há necessidade de um código especial para expedir e manipular mensagens de entrada. Quando um aplicativo faz uma chamada de método síncrono, o COM insere um loop de espera modal que manipula as respostas necessárias e envia mensagens de entrada para aplicativos capazes de processá-las.
O COM gerencia chamadas de método atribuindo um identificador chamado ID de thread lógico. Um novo é atribuído quando um usuário seleciona um comando de menu ou quando o aplicativo inicia uma nova operação COM. Chamadas subsequentes relacionadas à chamada COM inicial recebem a mesma ID de thread lógica que a chamada inicial.