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. COM fornece sincronização de chamadas apenas para apartamentos de thread único. Apartamentos multithreaded (contendo threads free-thread) não recebem chamadas ao fazer chamadas (no mesmo thread). 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, a saber:
-
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 espera. COM entra em um loop modal para aguardar a resposta, recebendo e despachando outras mensagens de forma 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. COM define cinco métodos assíncronos de IAdviseSink:
Observação
Enquanto COM está processando uma chamada assíncrona, chamadas síncronas não podem ser feitas. Por exemplo, a implementação de OnDataChange de um aplicativo de contêiner não pode conter uma chamada para IPersistStorage::Save. Essas chamadas são as únicas chamadas assíncronas suportadas pelo COM. Não há nenhuma maneira de criar uma interface personalizada que é assíncrona no momento.
-
Chamadas sincronizadas com entrada
-
Ao fazer chamadas sincronizadas de entrada, o objeto chamado deve concluir a chamada antes de gerar 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 através da função SendMessage , sem entrar em 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 gerar controle. Os seguintes métodos 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 os problemas que podem surgir do processamento assíncrono de mensagens, a maioria das chamadas de método COM são síncronas. Com a comunicação síncrona, não há necessidade de código especial para despachar e manipular mensagens recebidas. 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 despacha mensagens de entrada para aplicativos capazes de processá-las.
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. As chamadas subsequentes relacionadas à chamada COM inicial recebem a mesma ID de thread lógico que a chamada inicial.