INFO : Description et fonctionnement des modèles de threads OLE

IMPORTANT : Cet article est issu d'une traduction automatique réalisée par un logiciel Microsoft et non par un traducteur professionnel. Cette traduction automatique a pu aussi être révisée par la communauté Microsoft grâce à la technologie Community Translation Framework (CTF). Pour en savoir plus sur cette technologie, veuillez consulter la page http://support.microsoft.com/gp/machine-translation-corrections/fr. Microsoft vous propose en effet des articles traduits par des professionnels, des articles issus de traductions automatiques et des articles issus de traductions automatiques révisées par la communauté Microsoft, de manière à ce que vous ayez accès à tous les articles de notre Base de connaissances dans votre langue. Il est important de noter que les articles issus de la traduction automatique, y compris ceux révisés par la communauté Microsoft, peuvent contenir des erreurs de vocabulaire, de syntaxe ou de grammaire. Microsoft ne pourra être tenu responsable des imprécisions, erreurs, ainsi que de tout dommage résultant d’une traduction incorrecte du contenu ou de son utilisation par les clients.

La version anglaise de cet article est la suivante: 150777
Résumé
Les objets COM peuvent être utilisés dans plusieurs threads d'un processus. Les termes « Single-threaded Apartment » (STA) et « Multithread apartment (cloisonné) » (MTA) sont utilisé pour créer un cadre conceptuel pour décrire la relation betweenobjects et les threads, les relations de concurrence entre les objets, la meansby, la méthode appelle sont remies à un objet et les règles pour les pointeurs de passinginterface entre les threads. Composants et à leur clients choosebetween les modèles suivants de deux apartment (cloisonné) actuellement pris en charge par COM :

  1. Modèle d'ordonnancement cloisonné monothread (STA): un ou plusieurs threads dans un processus utilisent COM et les appels à des objets COM sont synchronisées avec les Interfaces COM sont marshalés entre les threads. Un cas dégénéré du modèle de thread cloisonné, où un seul thread dans un processus donné utilise COM, est appelé le modèle de threads unique. Dans le passé, les informations et la documentation de Microsoft ont parfois appelé le modèle STA simplement le « modèle d'apartment (cloisonné) ».
  2. Modèle de cloisonnement multithread (MTA): un ou plusieurs threads utilisent COM et les appels aux objets COM associés à l'agent MTA sont effectués directement par tous les threads associés à l'agent MTA sans aucun interposition du code du système entre l'appelant et l'objet. Dans la mesure où plusieurs clients simultanés peuvent appeler les objets plus ou moins simultanément (simultanément sur les systèmes multiprocesseurs), les objets doivent synchroniser leur état interne par eux-mêmes. Les interfaces ne sont pas marshalés entre les threads. Microsoft des informations et la documentation précédente a parfois ce modèle en tant que « modèle libre de threads. »
  3. Le modèle STA et le modèle MTA peuvent être utilisés dans le même processus. Cela est parfois appelé un processus « modèle mixte ».
Le MTA a été introduit dans NT 4.0 et est disponible dans Windows 95 avec DCOM95. Le modèle STA existe dans Windows NT 3.51 et Windows 95 ainsi que NT 4.0and Windows 95 avec DCOM95.
Plus d'informations

Vue d'ensemble

Les modèles de thread COM fournissent le mécanisme de composants qu'utiliserdifférents threading architectures de travailler ensemble. Ils providesynchronization également les services de composants qui en ont besoin. Par exemple, aparticular objet peut être conçue pour être appelée que par un seul thread andmay pas synchroniser des appels simultanés à partir de clients. Si ces une iscalled d'objet simultanément par plusieurs threads, il se bloque ou provoque des erreurs. Les mécanismes permettant de gérer cette interopérabilité de threadingarchitectures de COMprovides.

Même thread prenant en charge les composants doivent souvent des services de synchronisation. Par exemple, les composants qui ont une interface utilisateur graphique (GUI), ces contrôles d'asOLE/ActiveX, des incorporations actives sur place et les documents ActiveX, requièrent une synchronisation et de sérialisation des appels COM et messages.COM de la fenêtre fournit ces services de synchronisation pour ces composants peuvent bewritten sans code de synchronisation complexes.

Un « apartment » a plusieurs aspects interdépendants. Tout d'abord, il s'agit d'un logicalconstruct de réflexion à propos de l'accès concurrentiel, par exemple comment les threads sont liés à une série d'objets COM. Ensuite, il est qu'un ensemble de programmeurs de règles doit respecter les toreceive le comportement d'accès concurrentiel qu'ils attendent d'environnement COM. Enfin, il est le code fourni par le système qui permet aux programmeurs de respect de concurrencywith de thread pour les objets COM de gérer.

Le terme « apartment » provient d'une métaphore dans laquelle un processus est conceivedas une entité totalement distinctes, comme une « construction » qui est subdivisée ensemble d'intoa de connexes mais différents « paramètres régionaux » appelé « apartments ». Un apartmentis, un « conteneur logique » qui crée une association entre les objets et, dans certains cas, des threads. Les threads ne sont pas des apartments (cloisonnés), bien qu'il y a peut-être un thread asingle logiquement associé à un thread cloisonné dans le modèle STA. Les objets ne sont pas des apartments (cloisonnés), bien que chaque objet est associé à seulement un apartment (cloisonné) de plusieurs. Mais les appartements sont plus qu'un logicalconstruct ; leurs règles décrivent le comportement du système COM. Si vous therules des modèles d'apartment (cloisonné) ne sont pas suivies, les objets COM sont correctement notfunction.

Plus de détails

Un Single-threaded apartment (STA) est un ensemble d'objets COM associé au thread d'aparticular. Ces objets sont associées avec l'apartment (cloisonné) par beingcreated par le thread ou, plus précisément, étant tout d'abord exposée à la COMsystem (généralement par marshaling) sur le thread. UN STA est considéré comme aplace, un objet ou un proxy « résidence. » Si l'objet ou un proxy doit être accessible par un autre cloisonnement (dans le même ou un autre processus), pointeur d'itsinterface doit être marshalé à ce apartment (cloisonné) lorsqu'une nouvelle est de proxy créé. Si les règles du modèle apartment (cloisonné) appel systèmede de suivi, direct ne les autres threads du même processus sont autorisés sur cet objet ; thatwould violer la règle sur tous les objets dans un appartement donné s'exécuter sur le thread d'asingle. La règle existe, car la plupart du code en cours d'exécution dans un willfail STA à fonction correctement si s'exécutent sur des threads supplémentaires.

Le thread associé à un STA doit appeler CoInitialize orCoInitializeEx (NULL, COINIT_APARTMENTTHREADED) et doit récupérer anddispatch les messages de fenêtre pour les objets associés recevoir des incomingcalls. COM distribue et synchronise les appels aux objets dans une usingwindow les messages STA, comme décrit plus loin dans cet article.

Le « STA principal » est le thread qui appelle CoInitialize orCoInitializeEx(NULL,COINIT_APARTMENTTHREADED) tout d'abord un processus donné. Le STA principal d'un processus doit rester actif jusqu'à ce que tout le travail COM est completedbecause que certains objets in-process sont toujours chargés dans le STA principal, procéder plus loin dans cet article.

Windows NT 4.0 et DCOM95 introduisent un nouveau type d'apartment (cloisonné) appelée architecture-threaded apartment (MTA). Un agent MTA est un ensemble de contrôles d'objets COM un ensemble de threads dans le processus tel que n'importe quel thread peut appeler l'implémentation d'anyobject directement sans interposition du code du système. Des pointeurs d'interface à n'importe quel objet dans le MTA peuvent être passées entre le threadsassociated avec l'agent MTA sans avoir à être marshalés. Tous les threads dans le manuel Process qui appeler CoInitializeEx (NULL, COINIT_MULTITHREADED) sont des contrôles du MTA. Contrairement à la STA décrit ci-dessus, les threads dans un MTA faire notneed afin d'extraire et de distribuer les messages de fenêtre pour les appels entrants de toreceive objets associés. COM ne synchronise pas les appels aux objets dans anMTA. Objets dans un MTA doivent protéger leur état interne à partir de l'interaction de bythe de corruption de plusieurs threads simultanés et ils ne pouvez anyassumptions sur le contenu du constantbetween restant du stockage Local des threads différents appels de méthodes.

Un processus peut avoir n'importe quel nombre de stations, mais, au plus, peut y avoir un seul MTA. TheMTA se compose d'un ou plusieurs threads. Stations ont un seul thread. Threadbelongs, au maximum, un apartment (cloisonné). Les objets appartiennent à l'une et oneapartment uniquement. Des pointeurs d'interface doivent toujours être marshalées entre les apartments (bien que le résultat du marshaling peut être un pointeur direct plutôt que d'aproxy). Consultez les informations ci-dessous sur CoCreateFreeThreadedMarshaler.

Un processus choisit l'un des modèles de thread fournies par COM. Un modelprocess STA a un ou plusieurs des stations et ne dispose pas d'un agent MTA. Un agent MTA modèle processhas un MTA avec un ou plusieurs threads et qu'il n'a pas les stations. Un modèle mixte de processus a un MTA et n'importe quel nombre de stations.

Modèle de thread cloisonné

Le thread d'un STA doit appeler CoInitialize ou CoInitializeEx(NULL,COINIT_APARTMENTTHREADED) et doit récupérer et messagesbecause de fenêtre de dispatch COM utilise des messages de fenêtre pour synchroniser et de répartir les appels de deliveryof à un objet dans ce modèle. Consultez la section références ci-dessous plus d'informations.

Serveur qui prend en charge le modèle STA :

Dans le modèle STA, les appels à un objet sont synchronisées par COM dans la samemanner que validées dans une fenêtre de messages de fenêtre. Appelle aredelivered à l'aide de messages de fenêtre pour le thread qui a créé l'objet. Par conséquent, le thread de l'objet doit appeler andDispatchMessage Get/PeekMessage pour recevoir des appels. COM crée une fenêtre cachée des contrôles chaque STA. Un appel à un objet extérieur le STA est runtime byCOM transféré au thread de l'objet à l'aide d'un message de fenêtre validé dans la fenêtre de thishidden. Lorsque le thread associé à retrievesand STA l'objet distribue le message, la procédure de fenêtre pour la fenêtre masquée, également mis en œuvre par COM, le reçoit. La procédure de fenêtre est utilisée par le runtime de theCOM à « raccorder » le thread associé le STA étant la COMruntime sur les deux côtés de l'appel à partir du thread propriétaire de COM à la STA'sthread. Le runtime COM (en cours d'exécution dans le thread de le STA) appelle « up » via un stub d'aCOM fourni dans la méthode d'interface correspondante de l'objet. Le chemin d'accès de l'exécution du retour de l'appel de la méthode inverse de l'appel de « up », l'appel retourne le stub et le runtime COM, qui passe de controlback pour le thread d'exécution COM via un message de fenêtre, le canal returnsthrough puis le modèle COM à l'appelant d'origine.

Lorsque plusieurs clients appellent un objet STA, les appels sont automaticallyqueued dans la file d'attente de message par le transfert de mécanisme de contrôle utilisé dans le STA. L'objet reçoit un appel chaque fois que son STA récupère les messages anddispatches. Les appels sont synchronisés par COM dans thismanner, et parce que les appels sont toujours transmis sur le même threadassociated avec STA l'objet, Drawing d'implémentations de l'objet interface est nécessaire assurer la synchronisation.

Remarque: l'objet peut être entrée à nouveau si une methodimplementation interface récupère et distribue les messages pendant le traitement d'un methodcall, à l'origine d'un autre appel à être remis à l'objet par le même Acommon STA dans lequel ce problème se produit de façon est si un objet STA appelle un out-going(cross-apartment/cross-process) à l'aide de COM. Cette page est identique à themanner, dans lequel une procédure de fenêtre peut être entrée à nouveau si elle récupère les messages d'anddispatches lors du traitement d'un message. COM n'empêche pas de re-entrance sur le même thread, mais n'empêche pas l'exécution en simultané. Italso fournit un moyen par lequel COM. de réentrance peut être géré. Reportez-vous à la section références ci-dessous pour plus d'informations. L'objet n'est pas entrée à nouveau si la méthode implémentations n'appellent pas de son orotherwise apartment (cloisonné), récupérer et distribue les messages.

Responsabilités du client dans le modèle STA :

Code client s'exécutant dans un processus et/ou de la thread qui utilise les interfaces de mustmarshal modèle STA d'un objet entre les apartments (cloisonnés) par usingCoMarshalInterThreadInterfaceInStream et CoGetInterfaceAndReleaseStream.For exemple, si 1 de cloisonnement dans le client dispose d'un pointeur d'interface, andApartment 2 requiert l'utilisation de ce dernier, Appartement 1 doit marshaler l'interfaceusing CoMarshalInterThreadInterfaceInStream. L'objet de flux retourné bythis fonction est thread-safe et son pointeur d'interface doit être stockée ina direct à la mémoire variable accessible par Appartement 2. Appartement 2 doit interface de flux de passthis à CoGetInterfaceAndReleaseStream pour démarshaler interface sur l'objet sous-jacent et obtenir un pointeur à une proxythrough dans laquelle il peut accéder à l'objet.

Le compartiment principal d'un processus donné doit rester actif jusqu'à ce que le clienthas terminé tous les travaux de COM, car certains objets in-process sont chargées dans le principal-apartment (cloisonné). (Informations plus détaillées ci-dessous).

Modèle cloisonné multi-thread

Un agent MTA est la collection d'objets créés ou exposés par toutes le threadsin le processus qui ont appelé CoInitializeEx (NULL, COINIT_MULTITHREADED).

Remarque: les implémentations actuelles de COM permettent à un thread qui exécute COM d'initialisation notexplicitly pour faire partie du MTA. Un thread qui fait notinitialize COM est partie du MTA uniquement si elle commence à l'aide de COM après au moins un autre thread dans le processus a précédemment calledCoInitializeEx (NULL, COINIT_MULTITHREADED). (Il est même possible que COMitself peut avoir initialisé le MTA lorsque aucun thread client n'a explicitlydone donc ; par exemple, un thread associé à un STA callsCoGetClassObject/CoCreateInstance [Ex] sur un CLSID qui est marqué comme "ThreadingModel = libre » et COM crée implicitement un MTA dans les theclass objet est chargé.) Consultez les informations sur les threads modelinteroperability ci-dessous.

Toutefois, il s'agit d'une configuration qui peut provoquer des problèmes, ces violations d'asaccess, dans certaines circonstances. Par conséquent, il est stronglyrecommended que chaque thread que doit faire le travail de COM initialiser COM bycalling CoInitializeEx, puis, à la fin du travail de COM, callCoUninitialize. Le coût de « inutilement » l'initialisation du MTA est minime.

Threads MTA n'avez pas besoin de récupérer et de distribuer les messages car COM n'utilisent des messages de fenêtre dans ce modèle pour fournir des appels à un objet.

Serveur qui prend en charge le modèle MTA :

Dans le modèle MTA, les appels à un objet ne sont pas synchronisés par COM. Multipleclients pouvez appeler simultanément d'un objet qui prend en charge de cette ondifferent de threads, et l'objet doit fournir ces asevents, les mutex, les sémaphores, etc. des objets de synchronisation itsinterface/implémentations de méthodes à l'aide de la synchronisation. Objets MTA peuvent recevoir appel systèmede simultané de plusieurs clients out-of-process dans un pool de threadsbelonging de création de COM au processus de l'objet. Objets MTA peuvent recevoir appel systèmede simultanément plusieurs clients dans le processus sur plusieurs threads associés à theMTA.

Responsabilités du client dans le modèle MTA :

Code de client qui s'exécute dans un processus ou le thread qui utilise le ne modèle MTA ont marshaler des pointeurs d'interface d'un objet entre lui-même threads MTA etautres. Au lieu de cela, un thread MTA peut utiliser une pointerobtained de l'interface à partir d'un autre thread MTA comme un pointeur direct à la mémoire. Lorsqu'un clientthread effectue un appel à un objet out-of-process, il suspend jusqu'à la fin de callhas. Les appels peuvent arriver sur objets associés à l'agent MTA whileall des threads créés par l'application associées à l'agent MTA sortant des appels sont bloquées. Dans ce cas et en règle générale, les appels entrants sont remis onthreads fournie par le runtime COM.. Message ne sont pas les filtres (IMessageFilter) disponibles dans le modèle MTA.

Modèle mixte de threads

Un processus qui prend en charge le modèle mixte-threading utilisera un MTA et oneor plus de stations. Des pointeurs d'interface doivent être marshalés entre tous les apartmentsbut peut être utilisé sans marshaling dans le MTA. Les appels aux objets d'anSTA sont synchronisés par COM pour s'exécuter uniquement sur un thread tout en toobjects des appels dans le MTA ne sont pas. Toutefois, appelle dans un STA à un normallygo MTA par le biais de code fourni par le système et le commutateur à partir du thread STA à un MTAthread avant d'être remis à l'objet.

Remarque: consultez la documentation du Kit de développement logiciel sur CoCreateFreeThreadedMarshaler() et thediscussion de cette API ci-dessous pour des informations sur les cas où pointerscan direct utilisé et la façon dont un thread STA peuvent appeler directement dans un firstassociated de l'objet avec le MTA et vice versa, à partir de plusieurs appartements.

Choix du modèle de thread

Un composant peut choisir prendre en charge le modèle STA, le modèle MTA ou acombination des deux en utilisant le modèle mixte de threads. Par exemple, la possibilité d'anobject qui effectue des e/s étendues prendre en charge des MTA pour fournir des maximumresponse aux clients en autorisant les appels interface lors de l'i / Olatency. Sinon, un objet qui interagit avec l'almostalways de l'utilisateur choisit prendre en charge le STA pour synchroniser les appels COM entrants avec les opérations d'itsGUI. Il est plus facile de prise en charge le modèle STA, car COM providessynchronization. Le modèle MTA de prise en charge est plus difficile car pourla doit implémenter la synchronisation, mais la réponse aux clients est la synchronisation de la betterbecause est utilisée pour les plus petites sections de code, au lieu de cela thanfor l'appel de l'ensemble de l'interface fournie par COM.

Le modèle STA est également utilisé par Microsoft Transaction Server (MTS, nommé previouslycode « Viper ») et les objets de base de DLL de planification à exécuter dans l'environnement de theMTS devraient donc utiliser le modèle STA. Objets mis en œuvre pour le MTAmodel normalement fonctionne correctement dans un environnement MTS. Toutefois, ils seront runless efficacement, car ils utiliseront les primitives de threadsynchronization inutiles.

Le modèle de prise en charge de threads, les serveurs In-Process de marquage

Un thread utilise le modèle MTA s'il appelle CoInitializeEx(NULL,COINIT_MULTITHREADED) ou utilise COM sans l'initialiser. Un thread l'option modèle STA si elle appelle CoInitialize ou CoInitializeEx(NULL,COINIT_APARTMENTTHREADED).

Les API de CoInitialize contrôlent l'apartment (cloisonné) pour le code client et forobjects qui sont fournies dans. Exe, car codecan de démarrage de l'exécution de COM initialiser COM de la manière souhaitée.

Toutefois, un serveur in-process COM (fondés sur des DLL) ne le fait pas callCoInitialize/CoInitializeEx car ces API est ont été appelés par thetime le serveur DLL est chargée. Par conséquent, un serveur DLL doit utiliser Registre pour informer COM au modèle de thread qu'il prend en charge afin que canensure COM que le système fonctionne d'une manière qui soit compatible avec elle. Valeur nommée de calledThreadingModel de clé du composant CLSID\InprocServer32 est utilisé à cette fin comme suit :

  • Valeur ThreadingModel n'existe pas : prend en charge le modèle de threads unique.
  • ThreadingModel = apartment (cloisonné): prend en charge STA modèle.
  • ThreadingModel = Both : prend en charge modèle STA et MTA.
  • ThreadingModel = libre : prend en charge des MTA uniquement.
Remarque: ThreadingModel est une valeur nommée, pas une sous-clé d'asincorrectly InprocServer32 documenté dans certaines versions antérieures de la documentation de Win32.

Les serveurs in-process des modèles de thread sont abordés plus loin dans cet article. Ifan in-process server fournit de nombreux types d'objets (chacun avec sa propre uniqueCLSID), chaque type peut avoir une autre valeur ThreadingModel. Dans otherwords, le modèle de thread est par CLSID, pas par code/DLL du package. Toutefois, l'API désigne nécessaire de « amorçage » et la requête de procservers tous les (DLLGetClassObject(), DLLCanUnloadNow()) doit être thread-safe forany intra-serveur qui prend en charge plusieurs threads (c'est-à-dire un « apartment » de ThreadingModelvalue, les deux ou libre).

Comme indiqués précédemment, out-of-process des serveurs ne marquent pas eux-mêmes valeur ThreadingModel d'usingthe. Au lieu de cela, ils utilisent CoInitialize ou serveurs CoInitializeEx.DLL qui comptent s'exécuter out-of-process à l'aide de la fonctionnalité de « substitution » de COM (par exemple, la substitution fourni par le système DLLHOST. (EXE) suivez simplement les règles pour les serveurs de base de DLL ; Il n'y a dans ce cas aucune specialconsiderations.

Lorsque le Client et l'objet utilisent différents modèles de thread

Interaction entre un client et un objet out-of-process est simple, même lorsque les différents modèles de thread sont utilisées, car l'objet clientand sont dans des processus différents et COM est impliqué dans le passage d'appel systèmede le client à l'objet. Le modèle COM étant interposition entre la clientand du serveur, il fournit le code pour l'interopérabilité de la threadingmodels. Par exemple, si un objet STA est appelé simultanément par multipleSTA ou clients MTA, COM synchronise les appels en plaçant des correspondingwindow les messages dans la file d'attente de messages du serveur. Appel de l'objet STA receivesone chaque fois qu'il récupère et distribue les messages. L'interopérabilité de tous les combinationsof au modèle de thread sont autorisés et entièrement pris en charge betweenclients et objets d'out-of-process.

Interaction entre un client et un objet in-process qui utilise des modèles de differentthreading est plus compliquée. Bien que le serveur in-process, COMmust lui-même interpose entre le client et l'objet dans certains cas. Par exemple, un objet en cours prend en charge le modèle STA peut être calledconcurrently par plusieurs threads d'un client. COM ne peut pas autoriser le clientthreads accéder directement à l'interface l'objet car l'objet est notdesigned pour ce type d'accès simultané. Au lieu de cela, COM doit s'assurer que callsare synchronisés et effectuées uniquement par le thread associé le STA qui « contient » l'objet. En dépit de la complexité, interopérabilité d'ofthreading-modèle toutes les combinaisons sont autorisées entre les clients et en-procobjects.

Modèles de Out-of-Process (EXE) serveurs de thread

Voici trois catégories de serveurs out-of-process chaque le pouvez allumer l'éclairage utilisé par n'importe quel client COM, quel que soit le modèle de thread utilisé par ceclient :

  1. Serveur de modèle STA :

    Le serveur effectue le travail de COM dans un ou plusieurs des stations. Les appels entrants sont synchronisées par COM et livrées par le thread associé le STA dans laquelle l'objet a été créé. Les appels de méthode de fabrique de classe sont remis par le thread associé le STA qui inscrit la fabrique de classe. La fabrique de classe et de l'objet n'est pas nécessaire d'implémenter la synchronisation. Toutefois, l'implémentation doit synchroniser l'accès à toutes les variables globales utilisées par plusieurs stations. Le serveur doit utiliser CoMarshalInterThreadInterfaceInStream et CoGetInterfaceAndReleaseStreamto marshaler des pointeurs d'interface, éventuellement à partir d'autres serveurs, entre les stations. Le serveur peut éventuellement implémenter IMessageFilter dans chaque STA pour contrôler des aspects de la remise d'appel par COM. Un cas dégénéré est le serveur de modèle unique-threading qui effectue le travail de COM dans un STA
  2. Serveur de modèle MTA :

    Le serveur effectue le travail de COM dans un ou plusieurs threads qui appartiennent au MTA. Les appels ne sont pas synchronisés par COM. COM crée un pool de threads dans le processus du serveur, et un appel client est remis par un de ces threads. Threads n'avez pas besoin de récupérer et de distribuer les messages. La fabrique d'objet et de la classe doit implémenter la synchronisation. Le serveur n'a pas besoin de marshaler des pointeurs d'interface entre les threads.
  3. Serveur de modèle mixte :

    Reportez-vous à la section de cet article intitulée « mixte modèle de threads » pour plus d'informations.

Modèles dans les Clients de thread

Il existe trois catégories de clients :

  1. Client du modèle STA :

    Le client de COM fonctionne dans les threads associés à un ou plusieurs des stations. Le client doit utiliser CoMarshalInterThreadInterfaceInStream et CoGetInterfaceAndReleaseStream pour marshaler des pointeurs d'interface entre les stations. Un cas dégénéré est le client du modèle unique-threading qui effectue le travail de COM dans un STA Thread que le client entre COM fournie la boucle de message lorsqu'il effectue un appel sortant. Le client peut utiliser IMessageFilter pour gérer les rappels et le traitement des messages de la fenêtre lors de l'attente sur sortant des appels et autres problèmes de concurrence d'accès.
  2. Client du modèle MTA :

    Le client effectue COM dans un ou plusieurs threads qui appartiennent au MTA. Le client n'a pas besoin de marshaler des pointeurs d'interface entre ses threads. Le client ne peut pas utiliser IMessageFilter. Suspendre les threads du client lorsqu'il effectue un appel de COM pour un objet out-of-process et reprend lorsque l'appel retourne. Appels entrants arrivent sur les threads créés par COM et managées.
  3. Client du modèle mixte :

    Reportez-vous à la section de cet article intitulée « mixte modèle de threads » pour plus d'informations.

Modèles dans In-Process (DLL) serveurs de thread :

Il existe quatre catégories de serveurs in-process, chacun d'eux peut être le client COM de byany utilisé quel que soit le modèle de thread utilisé par ce client. Toutefois, les serveurs in-process doivent fournir le code de marshaling pour toute interface personnalisée (non-définie par le système) qu'ils implémentent s'ils sont en charge threadingmodel interopérabilité car qui nécessite généralement cette interface de marshaling COM entre les apartments (cloisonnés) clients. Les quatre catégories sont les suivantes :

  1. Serveur in-process qui prend en charge le thread STA (single « main »)-aucune valeur ThreadingModel :

    Un objet fourni par ce serveur s'attend à être accessible par le même STA de client par lequel il a été créé. En outre, le serveur s'attend à tous ses points d'entrée, tels que DllGetClassObject DllCanUnloadNow et les données globales d'être accessible par le même thread (celle associée le STA principal). Les serveurs qui existait avant l'introduction de multi-threading dans COM appartiennent à cette catégorie. Ces serveurs ne sont pas conçus pour être accessibles par plusieurs threads pour COM crée tous les objets fournis par le serveur dans le STA principal du processus et les appels aux objets sont remis par le thread associé le STA principal. Autres apartments (cloisonnés) clients accéder à l'objet par le biais de serveurs proxy. Appels à partir d'autres apartments (cloisonnés) accédez à partir du proxy au relais dans le STA principal (marshaling inter-threads), puis à l'objet. Ce regroupement permet de COM pour synchroniser les appels à l'objet et les appels sont remis par le STA dans laquelle l'objet a été créé. Marshaling inter-threads est lent par rapport à l'appelant direct, il est donc recommandé que ces serveurs soient réécrites pour prendre en charge les stations multiples (catégorie 2).
  2. Serveur in-process prenant en charge le modèle de thread unique cloisonné (STA plusieurs) - marqué avec ThreadingModel = apartment (cloisonné) :

    Un objet fourni par ce serveur s'attend à être accessible par le même STA de client par lequel il a été créé. Par conséquent, il est similaire à un objet fourni par un seul thread serveur in-process. Toutefois, les objets fournis par ce serveur peuvent être créés dans plusieurs stations du processus, afin que le serveur doit concevoir ses points d'entrée, tels que DllGetClassObject, DllCanUnloadNow et globale des données pour une utilisation multithread. Par exemple, si deux stations d'un processus de créent simultanément les deux instances de l'objet in-process, DllGetClassObject peut-être être appelé simultanément par les deux stations. De même, DllCanUnloadNow doit être écrits afin que le serveur est protégé contre les déchargé lorsque le code est en cours d'exécution sur le serveur.

    Si le serveur fournit uniquement une instance de la fabrique de classe pour créer tous les objets, la mise en oeuvre de fabrique de classe doit également être adapté pour une utilisation multithread, car il est accessible par plusieurs clients de stations. Si le serveur crée une nouvelle instance de la fabrique de classe chaque DllGetClassObject est appelée, la fabrique de classe n'a pas besoin d'être thread-safe. Toutefois, l'implémentation doit synchroniser l'accès à toutes les variables globales.

    Les objets COM créés par la fabrique de classe n'est pas nécessaire être thread-safe. Toutefois, l'accès des variables globales doivent être synchronisées par l'implémenteur. Une fois créé par un thread, l'objet est toujours accédé par le biais de thread synchronisation et tous les appels à l'objet par les apartments (cloisonnés) COM Client différents que le STA dans laquelle l'objet a été créé doit accéder à l'objet par le biais de serveurs proxy. Ces proxies sont créés lorsque le client marshale l'interface entre les apartments (cloisonnés).

    Tout client qui crée un objet STA, par le biais de la fabrique de classe obtient un pointeur direct vers l'objet. Cela est différent de celui des objets monothread in-process, où seul le STA principal du client obtient un pointeur direct à l'objet et toutes les autres stations qui créent le gain de l'accès à l'objet via un proxy. Car il est lent par rapport à l'appel direct de marshaling inter-threads, vitesse peut être améliorée considérablement en modifiant un seul thread serveur in-process pour la prise en charge de plusieurs stations.
  3. Serveur in-process prenant en charge uniquement les MTA - marqué avec ThreadingModel = libre :

    Un objet fourni par ce serveur est sécurisé pour seulement le MTA. Il implémente sa propre synchronisation et est accessible par plusieurs threads clients en même temps. Ce serveur peut présenter un comportement qui n'est pas compatible avec le modèle STA. (Par exemple, par son utilisation de la file d'attente de messages Windows d'une manière qui interrompt la pompe de messages de modèle STA.) En outre, en marquant le modèle de thread de l'objet en tant que « Libre », l'implémentation de l'objet est suivant s'affiche : cet objet peut être appelé à partir de n'importe quel thread du client, mais cet objet également peut passer des pointeurs d'interface directement (sans marshaling) à tous les threads qu'il a créé et ces threads peuvent effectuer des appels à travers ces pointeurs. Par conséquent, si le client passe un pointeur d'interface vers un objet implémenté par le client (par exemple, un récepteur) à cet objet, il peut choisir de rappeler par ce pointeur d'interface à partir de n'importe quel thread qu'il a créé. Si le client est un STA, un appel direct à partir d'un thread qui est différent du thread qui a créé l'objet récepteur sera erreur (comme illustré dans les 2 ci-dessus). Par conséquent, COM toujours permet de garantir que les clients dans les threads associés à un STA accéder à ce type d'objet in-process uniquement par l'intermédiaire d'un proxy. En outre, ces objets ne doivent pas regrouper avec le marshaleur libre de threads car qui leur permet de s'exécuter directement sur des threads STA.
  4. Serveur in-process qui prend en charge le modèle cloisonné et libre de threads - marqué avec ThreadingModel = les deux :

    Un objet fourni par ce serveur implémente sa propre synchronisation et est accessible simultanément par plusieurs appartements de client. En outre, cet objet est créé et utilisé directement, au lieu de via un proxy, STA ou MTA d'un processus client. Dans la mesure où cet objet est utilisé directement dans les stations, le serveur doit marshaler des interfaces d'objets, et éventuellement d'autres serveurs, entre les threads de sorte que son accès à n'importe quel objet de manière appropriée de thread est garanti. En outre, en marquant le modèle de thread de l'objet en tant que « Les deux », l'implémentation de l'objet est suivant s'affiche : cet objet peut être appelé à partir de n'importe quel thread du client, mais tous les rappels à partir de cet objet sur le client seront effectuées uniquement sur le « apartment » dans laquelle l'objet a reçu le pointeur d'interface vers l'objet de rappel. COM permet à ce type d'objet doit être créé directement dans un STA, ainsi que dans un agent MTA du processus client.

    Car n'importe quel apartment (cloisonné) qui crée un tel objet toujours obtienne un pointeur direct plutôt qu'un pointeur de proxy, ThreadingModel « Both » objets fournissent des améliorations de performances sur les objets de « Libre » ThreadingModel lors du chargement dans un STA.

    Un ThreadingModel « Les deux » objet est également conçu pour accès MTA (il est en interne complètement thread-safe), elle peut accélérer les performances par agrégation avec le marshaleur fourni par CoCreateFreeThreadedMarshaler. Cet objet fourni par le système est regroupé dans les objets en appelant et personnalisé marshale direct des pointeurs vers l'objet dans toutes les apartments (cloisonnés) dans le processus. Clients dans n'importe quel apartment, STA et MTA, peuvent alors accéder à l'objet directement au lieu de via un proxy. Par exemple, un client du modèle STA crée l'objet en cours dans STA1 et marshale l'objet STA2. Si l'objet n'agrège pas le marshaleur libre de threads avec des, STA2 accède à l'objet via un proxy. Dans ce cas, le marshaleur libre de threads fournit STA2 avec un pointeur direct vers l'objet

    Remarque: être particulièrement vigilant lors de l'agrégation avec le marshaleur libre de threads. Par exemple, supposons qu'un objet qui est marqué comme ThreadingModel « Les deux » (et en les regroupant par le marshaleur libre de threads) possède une donnée membre qui est un pointeur d'interface vers un autre objet dont ThreadingModel est « Apartment ». Puis supposent qu'un STA crée le premier objet et lors de la création, le premier objet crée le deuxième objet. Selon les règles décrites ci-dessus, le premier objet détient désormais un pointeur direct vers le deuxième objet. Supposons maintenant que le STA marshale le pointeur d'interface vers le premier objet à un autre appartement. Car les première agrégats d'objet avec la libre - threaded marshaleur, un pointeur direct vers le premier objet est donné à la cloison du deuxième. Si le cloisonnement deuxième appelle ensuite via ce pointeur et que cet appel entraîne le premier objet à appeler via le pointeur d'interface vers le deuxième objet, puis une erreur s'est produite, car le deuxième objet n'est pas censé être appelée directement à partir de le « apartment » deuxième. Si le premier objet détient un pointeur à un proxy vers le deuxième objet, plutôt qu'un pointeur direct, cela provoquera une erreur différente. Proxy du système est également des objets COM qui sont associés au cloisonnement qu'un seul. Leur suivi de leur apartment (cloisonné) afin d'éviter certains circularities. Ainsi, un objet appelant sur un proxy associé à un « apartment » autre que le thread sur lequel l'objet est en cours d'exécution reçoit le retour RPC_E_WRONG_THREAD à partir du proxy et l'appel échouera.

Interopérabilité du modèle entre les Clients et les objets de processus de Threading

Toutes les combinaisons d'interopérabilité du modèle de thread sont autorisés à betweenclients et objets in-process.

COM permet à tous les clients du modèle STA interopérer avec des objets unique-threadingin-proc en accédant à l'objet dans les mainSTA du client et à marshaler vers le client qui a appelé CoCreateInstance [Ex] STA.

Si un agent MTA dans un client crée un serveur in-process du modèle STA, COM tourne « hôte » STA dans le client. Cet hôte STA crée l'objet et le pointeur d'interface est marshalé vers le MTA. De même, lorsqu'un STAcreates, un serveur in-process MTA, COM se mette en rotation un MTA d'hôte dans lequel l'objectis créé et remarshalées vers l'interopérabilité STA entre le modèle de thread de thesingle et le modèle MTA est gérée de la même façon, car le modèle de thread de thesingle est simplement un cas dégénéré du modèle STA.

Marshaling de code doit être fournie pour n'importe quelle interface personnalisé implémentant une procserver si elle veut prendre en charge de l'interopérabilité nécessitant COMto marshaler l'interface entre les apartments (cloisonnés) clients. Voir la REFERENCESsection ci-dessous pour plus d'informations.

Relation entre le modèle de thread et l'objet de fabrique de classe retourné

Une définition précise des serveurs in-process « chargées dans « isexplained des apartments (cloisonnés) dans les deux étapes suivantes :

  1. Si la DLL qui contient la classe de serveur in-process n'a pas encore été chargé (mappés dans l'espace d'adressage de processus) par le chargeur du système d'exploitation, cette opération est effectuée et COM Obtient l'adresse de la fonction DLLGetClassObject exportée par la DLL. Si la DLL a déjà été chargée par un thread associé à n'importe quel apartment (cloisonné), cette étape est ignorée.
  2. COM utilise le thread (ou, dans le cas d'un des threads MTA) associés à le « apartment » « chargement » pour appeler la fonction DllGetClassObject exportée par la DLL de demander le CLSID de la classe nécessaire. L'objet de fabrique retournée est ensuite utilisé pour créer des instances des objets de la classe.

    La deuxième étape (l'appel DllGetClassObject par COM) se produit chaque fois qu'un client appelle CoGetClassObject/CoCreateIntance [Ex], même à partir de dans le même apartment. En d'autres termes, DllGetClassObject peut être appelée de nombreuses fois par un thread associé à la même apartment (cloisonné) ; tout repose sur le nombre de clients dans cette cloison essayez d'obtenir l'accès à un objet de fabrique de classe pour cette classe.
Auteurs des implémentations de la classe et, au final, l'auteur de la DLLpackage d'un ensemble de classes ont la pleine liberté de choisir l'objet whatfactory pour renvoyer en réponse à la functioncall de DllGetClassObject. L'auteur du package DLL a l'ultime dites le code « derrière » le point d'entrée unique à l'échelle de la DLL DllGetClassObject() étant le droit de premier et le dernier potentiellement dispose de l'à décider quoi faire. Les possibilités de threetypical sont :

  1. DllGetClassObject retourne un objet de fabrique de classe unique par le thread appelant (ce qui signifie qu'un seul objet de fabrique de classe par STA et potentiellement plusieurs fabriques de classes dans le MTA).
  2. DllGetClassObject retourne toujours le même objet de fabrique de classe, quel que soit l'identité de la thread d'appel ou le type d'apartment (cloisonné) associée au thread appelant.
  3. DllGetClassObject retourne un objet de fabrique de classe unique par appel apartment (cloisonné) (un par Apartment (cloisonné) STA et MTA).
Il existe autres possibilités pour la relation entre l'objet de fabrique de classe retournés et les appels toDllGetClassObject (par exemple classe comme nouveau objet de fabrique par appel à DllGetClassObject), mais ils notpresently semble être particulièrement utile.

Résumé du Client et l'objet modèles de thread pour les serveurs In-Process

Le tableau suivant résume l'interaction entre les modèles de differentthreading lorsqu'un client thread premier appelle CoGetClassObject sur aclass qui est implémenté comme un serveur in-process.

Types de clients/threads :

  • client s'exécute dans un thread associé le STA « main » (premier thread à appeler CoInitialize ou CoInitializeEx avec indicateur de COINIT_APARTMENTTHREADED)-appelez cette STA0 (également appelé modèle de thread unique).
  • client s'exécute dans un thread associé dans n'importe quel autre appel STA [ASCII 150] STA *.
  • client s'exécute dans un thread associé dans le MTA.
Types de serveurs DLL :

  • Serveur ne possède aucune clé ThreadingModel--nous l'appellerons « None ».
  • Serveur est marqué « Apartment »--appeler cette « Apt. »
  • Serveur est marqué « Libre ».
  • Serveur est marqué « Both ».
Lors de la lecture du tableau ci-dessous, gardez l'esprit le fait au-dessus de la définition de « chargement » d'un serveur dans un appartement.
Client     Server     Result------     ------     -----------------------------------------STA0       None       Direct access; server loaded into STA0STA*       None       Proxy access; server loaded into                      STA0.MTA        None       Proxy access; server loaded into STA0; STA0 created                      automatically by COM if necessary;STA0       Apt        Direct access; server loaded into STA0STA*       Apt        Direct access; server loaded into STA*MTA        Apt        Proxy access; server loaded into anSTA created automatically by COM.STA0       Free       Proxy access; server is loaded into MTAMTA created automatically by COM if necessary.STA*       Free       Same as STA0->FreeMTA        Free       Direct accessSTA0       Both       Direct access; server loaded into STA0STA*       Both       Direct access; server loaded into STA*MTA        Both       Direct access; server loaded into the MTA				
Références
Documentation SDK sur les CoRegisterMessageFilter() et les IMessageFilterinterface.

Pour plus d'informations, consultez les articles suivants dans la Base de connaissances de Microsoft :
136885 Les Threads OLE doivent distribuer les Messages
137629 Interface personnalisée d'objet in-process dans le Client du modèle d'apartment (cloisonné)

Avertissement : Cet article a été traduit automatiquement.

Propriétés

ID d'article : 150777 - Dernière mise à jour : 03/20/2016 08:32:00 - Révision : 3.0

  • kbinfo kbmt KB150777 KbMtfr
Commentaires