Partager via


Prise en charge des threads dans Office

Cet article fournit des informations sur la prise en charge du thread dans le modèle objet Microsoft Office. Le modèle objet Office n’est pas thread-safe, mais il est possible d’utiliser plusieurs threads dans une solution Office. Les applications Office sont des serveurs COM (Component Object Model). COM permet aux clients d’appeler des serveurs COM sur des threads arbitraires. Pour les serveurs COM qui ne sont pas thread safe, COM fournit un mécanisme permettant de sérialiser des appels simultanés afin qu’un seul thread logique s’exécute sur le serveur à tout moment. Ce mécanisme est connu sous le nom de modèle de "Single-Threaded Apartment" (STA). Étant donné que les appels sont sérialisés, les appelants peuvent être bloqués pendant des périodes de temps pendant que le serveur est occupé ou gère d’autres appels sur un thread d’arrière-plan.

S’applique à : Les informations contenues dans cette rubrique s’appliquent aux projets de niveau document et aux projets de complément VSTO. Consultez les fonctionnalités disponibles par type d’application et de projet Office.

Connaissances requises lors de l’utilisation de plusieurs threads

Pour travailler avec plusieurs threads, vous devez avoir au moins une connaissance de base des aspects suivants de la multithreading :

  • API Windows

  • Concepts de multithreading COM

  • Concurrency

  • Synchronization

  • Marshaling

    Pour obtenir des informations générales sur le multithreading, consultez Threading géré.

    Office s’exécute dans le STA principal. Comprendre les implications de cette opération permet de comprendre comment utiliser plusieurs threads avec Office.

Scénario de multithreading de base

Le code dans les solutions Office s’exécute toujours sur le thread d’interface utilisateur principal. Vous souhaiterez peut-être améliorer les performances de l’application en exécutant une tâche distincte sur un thread d’arrière-plan. L’objectif est d’effectuer deux tâches apparemment à la fois au lieu d’une tâche suivie de l’autre, ce qui doit entraîner une exécution plus fluide (la principale raison d’utiliser plusieurs threads). Par exemple, vous pouvez avoir votre code d’événement sur le thread d’interface utilisateur Excel principal, et sur un thread d’arrière-plan, vous pouvez exécuter une tâche qui collecte des données à partir d’un serveur et met à jour les cellules de l’interface utilisateur Excel avec les données du serveur.

Threads d’arrière-plan qui appellent le modèle objet Office

Lorsqu’un thread d’arrière-plan effectue un appel à l’application Office, l’appel est automatiquement acheminé à travers la frontière STA. Toutefois, il n’existe aucune garantie que l’application Office peut gérer l’appel au moment où le thread d’arrière-plan l’effectue. Il existe plusieurs possibilités :

  1. L’application Office doit pomper les messages pour que l’appel ait la possibilité d’entrer. S'il s'agit d'un traitement lourd sans céder le contrôle, cela peut prendre du temps.

  2. Si un autre thread logique se trouve déjà dans l’appartement, le nouveau thread ne peut pas entrer. Cela se produit souvent lorsqu'un thread logique entre dans l'application Office, puis effectue un appel réentrant à l'appartement de l'appelant. L’application est bloquée en attendant que cet appel retourne.

  3. Excel peut être dans un état de sorte qu’il ne peut pas gérer immédiatement un appel entrant. Par exemple, l’application Office peut afficher une boîte de dialogue modale.

    Pour les possibilités 2 et 3, COM fournit l’interface IMessageFilter . Si le serveur l’implémente, tous les appels entrent via la méthode HandleIncomingCall . Pour la possibilité 2, les appels sont automatiquement rejetés. Pour la possibilité 3, le serveur peut rejeter l’appel, en fonction des circonstances. Si l’appel est rejeté, l’appelant doit décider de ce qu’il faut faire. Normalement, l’appelant implémente IMessageFilter, auquel cas il serait averti du rejet par la méthode RetryRejectCall .

    Toutefois, dans le cas des solutions créées à l’aide des outils de développement Office dans Visual Studio, COM Interop convertit tous les appels rejetés en un COMException (« Le filtre de messages indique que l’application est occupée »). Chaque fois que vous effectuez un appel de modèle objet sur un thread d’arrière-plan, vous devez être prêt à gérer cette exception. En règle générale, cela implique une nouvelle tentative pendant un certain temps, puis l’affichage d’une boîte de dialogue. Toutefois, vous pouvez également créer le thread d’arrière-plan en tant que STA, puis inscrire un filtre de message pour ce thread pour gérer ce cas.

Démarrer le thread correctement

Lorsque vous créez un thread STA, définissez l’état de l’appartement sur STA avant de démarrer le thread. L’exemple de code suivant montre comment procéder.

System.Threading.Thread t = new System.Threading.Thread(AnObject.aMethod);

t.SetApartmentState(System.Threading.ApartmentState.STA);
t.Start();

Pour plus d’informations, consultez Meilleures pratiques pour le threading managé.

Formulaires sans fenêtre modale

Un formulaire sans mode permet un certain type d’interaction avec l’application pendant l’affichage du formulaire. L’utilisateur interagit avec le formulaire et le formulaire interagit avec l’application sans fermer. Le modèle objet Office prend en charge les formulaires non-modals gérés ; toutefois, ils ne doivent pas être utilisés dans un thread d’arrière-plan.