Je ne peux pas m'en empêcher de publier cela, bien que ce ne soit pas une réponse directe à la question.
Il y a un brillant article MSKB de The Golden Ages of Com: Info: descriptions et fonctionnement des modèles de filetage ole. Toujours là, et a toutes les informations pertinentes. Le fait est que vous ne devez pas vous soucier de savoir s'il y a un maréchalage ou non, si vous suivez les règles. Enregistrez simplement votre objet en tant que ThreadingModel=Both
, agréger le commissaire franc-seh CoCreateFreeThreadedMarshaler
, et être fait. Com fera le maréchalage si nécessaire, de la meilleure façon possible. Selon le modèle d'appartement du client, le code client peut recevoir le pointeur direct vers votre interface, s'il suit également les règles.
Toute interface "Alien" que vous pouvez recevoir lorsqu'une méthode de votre interface est appelée sera valide dans la portée de l'appel, car vous restez sur le même fil. Si vous n'avez pas besoin de le stocker, c'est tout ce qui compte.
Si toutefois vous avez besoin de mettre en cache l'interface "extraterre CoMarshalInterThreadInterfaceInStream
/CoGetInterfaceAndReleaseStream
:
Pour le stocker:
- Entrez la section critique;
- appel
CoMarshalInterThreadInterfaceInStream
et stocker le IStream
pointeur dans un champ membre;
- Laisser la section critique;
Pour le récupérer
- Entrez la section critique;
- appel
CoGetInterfaceAndReleaseStream
Pour récupérer l'interface
- appel
CoMarshalInterThreadInterfaceInStream
et rangez-le à nouveau comme IStream
pour toute utilisation future
- Laisser la section critique;
- Utilisez l'interface dans la portée de l'appel actuel
Pour le libérer:
- Lorsque vous n'avez plus besoin de le garder, libérez simplement le stocké
IStream
(à l'intérieur de la section critique).
Si l'objet "extraterre CoGetInterfaceAndReleaseStream
. Cependant, vous ne devez faire aucune hypothèse, et vous n'avez vraiment pas besoin de savoir si l'objet avec lequel vous traitez est l'objet d'origine ou un proxy de maréchauffer com.
Cela peut être légèrement optimisé en utilisant CoMarshalInterface
avec MSHLFLAGS_TABLESTRONG
/ CoUnmarshalInterface
/ IStream::Seek(0, 0)
/ CoReleaseMarshalData
à la place de CoGetInterfaceAndReleaseStream
/CoGetInterfaceAndReleaseStream
, pour désarracher la même interface que de nombreuses fois que nécessaire sans libérer le flux.
Des scénarios de mise en cache plus complexes (et peut-être plus efficaces) sont possibles, impliquant un stockage local de fil. Cependant, je crois que ce serait un exagéré. Je n'ai fait aucun moment, mais je pense que les frais généraux CoMarshalInterThreadInterfaceInStream
/CoGetInterfaceAndReleaseStream
est vraiment bas.
Cela dit, si vous avez besoin de maintenir un état qui Stocke toutes les ressources ou objets qui peuvent nécessiter une affinité thread, à part les interfaces COM susmentionnées, vous ne devrait pas Marquez votre objet comme ThreadingModel=Both
ou agréger le FTM.