Suporte a threading no Office
Este artigo fornece informações sobre como o threading é suportado no modelo de objeto do Microsoft Office. O modelo de objeto do Office não é thread safe, mas é possível trabalhar com vários threads em uma solução do Office. Os aplicativos do Office são servidores COM (Component Object Model). COM permite que os clientes chamem servidores COM em threads arbitrários. Para servidores COM que não são thread safe, o COM fornece um mecanismo para serializar chamadas simultâneas para que apenas um thread lógico seja executado no servidor a qualquer momento. Esse mecanismo é conhecido como modelo de apartamento de thread único (STA). Como as chamadas são serializadas, os chamadores podem ser bloqueados por períodos de tempo enquanto o servidor está ocupado ou está manipulando outras chamadas em um thread em segundo plano.
Aplica-se a: As informações neste tópico se aplicam a projetos de nível de documento e projetos de suplemento VSTO. Consulte Recursos disponíveis por aplicativo e tipo de projeto do Office.
Conhecimento necessário ao usar vários threads
Para trabalhar com vários threads, você deve ter pelo menos conhecimento básico dos seguintes aspectos do multithreading:
APIs do Windows
Conceitos multithreaded COM
Simultaneidade
Sincronização
Marshaling
Para obter informações gerais sobre multithreading, consulte Threading gerenciado.
O Office é executado no STA principal. Compreender as implicações disso torna possível entender como usar vários threads com o Office.
Cenário básico de multithreading
O código nas soluções do Office sempre é executado no thread principal da interface do usuário. Talvez você queira suavizar o desempenho do aplicativo executando uma tarefa separada em um thread em segundo plano. O objetivo é concluir duas tarefas aparentemente ao mesmo tempo, em vez de uma tarefa seguida pela outra, o que deve resultar em uma execução mais suave (a principal razão para usar vários threads). Por exemplo, você pode ter seu código de evento no thread principal da interface do usuário do Excel e, em um thread em segundo plano, pode executar uma tarefa que reúne dados de um servidor e atualiza células na interface do usuário do Excel com os dados do servidor.
Threads em segundo plano que chamam o modelo de objeto do Office
Quando um thread em segundo plano faz uma chamada para o aplicativo do Office, a chamada é automaticamente empacotada através do limite do STA. No entanto, não há garantia de que o aplicativo do Office pode manipular a chamada no momento em que o thread em segundo plano a faz. Há várias possibilidades:
O aplicativo do Office deve bombear mensagens para que a chamada tenha a oportunidade de entrar. Se ele está fazendo processamento pesado sem ceder, isso pode levar tempo.
Se outro thread lógico já estiver no apartamento, o novo thread não poderá entrar. Isso geralmente acontece quando um thread lógico entra no aplicativo do Office e, em seguida, faz uma chamada de reentrada de volta para o apartamento do chamador. O aplicativo está bloqueado aguardando o retorno da chamada.
O Excel pode estar em um estado tal que não pode lidar imediatamente com uma chamada de entrada. Por exemplo, o aplicativo do Office pode estar exibindo uma caixa de diálogo modal.
Para as possibilidades 2 e 3, COM fornece a interface IMessageFilter . Se o servidor implementá-lo, todas as chamadas entrarão por meio do método HandleIncomingCall . Para a possibilidade 2, as chamadas são automaticamente rejeitadas. Para a possibilidade 3, o servidor pode rejeitar a chamada, dependendo das circunstâncias. Se a chamada for rejeitada, o chamador deve decidir o que fazer. Normalmente, o chamador implementa IMessageFilter, caso em que seria notificado da rejeição pelo método RetryRejectedCall .
No entanto, no caso de soluções criadas usando as ferramentas de desenvolvimento do Office no Visual Studio, a interoperabilidade COM converte todas as chamadas rejeitadas em um COMException ("O filtro de mensagem indicou que o aplicativo está ocupado"). Sempre que você fizer uma chamada de modelo de objeto em um thread em segundo plano, deverá estar preparado para lidar com essa exceção. Normalmente, isso envolve tentar novamente por um determinado período de tempo e, em seguida, exibir uma caixa de diálogo. No entanto, você também pode criar o thread em segundo plano como STA e, em seguida, registrar um filtro de mensagem para esse thread para lidar com esse caso.
Inicie o thread corretamente
Quando você cria um novo thread STA, defina o estado do apartamento como STA antes de iniciar o thread. O exemplo de código a seguir demonstra como fazer isso.
System.Threading.Thread t = new System.Threading.Thread(AnObject.aMethod);
t.SetApartmentState(System.Threading.ApartmentState.STA);
t.Start();
Para obter mais informações, consulte Práticas recomendadas de threading gerenciado.
Formulários sem janela restrita
Um formulário sem janela restrita permite algum tipo de interação com o aplicativo enquanto o formulário é exibido. O usuário interage com o formulário, e o formulário interage com o aplicativo sem fechar. O modelo de objeto do Office oferece suporte a formulários sem modo gerenciados; no entanto, eles não devem ser usados em um thread em segundo plano.