2013-03-14 5 views
10

Lors de l'implémentation de IComMethodEvents, vous obtenez trois événements.Corrélation IComMethodEvents

  1. OnMethodCall
  2. OnMethodException
  3. OnMethodReturn

L'objectif de ce que je suis en train de faire est de vous connecter les temps d'appel par méthode dans les composants COM +.

Le temps de l'événement peut être récupéré à l'aide lTime et lMicroTime dans la structure COMSVCSEVENTINFO en se connectant ce temps dans les deux OnMethodCall et OnMethodReturn je devrais être en mesure de calculer le temps d'appel, mais comment puis-je être sûr que les deux les événements sont liés. En testant, il semble que je devrais être capable d'utiliser l'objet activé Just-in-time (JIT) oid

Y a-t-il des problèmes à le faire comme cela ou existe-t-il d'autres façons? Un problème qui pourrait être que je vois le oid est fréquemment réutilisé donc si les événements pour une raison quelconque sont déclenchés dans le désordre il pourrait être un peu plus difficile d'implémenter la corrélation.

Mise à jour 1:

D'autres tests montre que oid ne suffit pas dans un scénario multi-utilisateur. Le même objet est utilisé en même temps, donc la corrélation doit être faite en utilisant au moins oid et original caller. Une question de suivi serait: Comment obtenir l'appelant d'origine d'un abonné à un événement COM +?

Mise à jour 2:

Je viens de trouver IComMethod2Events. La différence est que les événements ont un identifiant du thread exécutant l'appel. Il semble prometteur dans les tests et je ne peux pas imaginer un scénario où la corrélation pourrait échouer. Le modèle de thread pour les composants COM + est Any Apartment.

Mise à jour 3

Dans cet article Creating COM+ PerfMon Counters to Monitor COM+ Dataoid est utilisé. Je ne pense pas que cela soit suffisant dans un appartement multithread.

Remarque: Je vais éventuellement l'implémenter dans Delphi, j'ai donc ajouté la balise Delphi. J'ai également ajouté la balise C# parce que les chances sont que le langage utilisé pour implémenter l'interface n'est pas important du tout. Mise à jour: Ajout tentant de la balise C++ juste pour attirer l'attention de quelqu'un qui a déjà utilisé ce truc auparavant.

+0

Un outil pour surveiller les transactions COM +: ['AppMetrics'] (http://www.xtremesoft.com/solutions/white_paper_transactions.html). Peut-être utile et vous pouvez comprendre comment ils font la surveillance. –

+0

Cette page peut également vous être utile, ['MSDN COM + Tracking'] (http://msdn.microsoft.com/fr-fr/library/windows/desktop/dd179218 (v = vs.85) .aspx). –

+0

@LURD merci pour les liens. Lisez un peu du lien MSDN et COM + Instrumentation vous conduira éventuellement aux événements du Q. COM + Tracking vous permettra d'obtenir les données que COM + recueille pour vous mais seulement jusqu'au niveau du composant (je pense). –

Répondre

2

... si les événements pour une raison quelconque sont tirés hors d'usage ...

Ils ne le font jamais. L'éditeur d'événements système COM + déclenche ces événements à l'aide du service COM + Events. L'invocation d'un événement est synchrone du point de vue de l'éditeur d'événements. Lorsqu'un éditeur déclenche un événement, il ne procède pas au suivant tant que tous les abonnés n'ont pas terminé le traitement de l'événement déclenché. Tout naturellement, les événements OnMethodReturn/OnMethodException ne sont pas publiés avant de correspondre aux OnMethodCall. Je me souviens avoir lu des KB concernant les conditions de course/les abonnements cassés dans les événements COM +. À ma connaissance, tous ces bogues ont été traités dans divers Service Packs pour Windows 2000. Cependant, je n'essaie pas de rester à jour dans ce domaine. Lors de la mise en œuvre de IComMethod2Events, vous vous abonnez au même abonnement transitoire que pour IComMethodEvents

Donc, l'ordre des événements déclenchés est le même aussi.

... donc la corrélation doit être fait en utilisant au moins oid et original caller ...

À ce stade, je ne suis vraiment pas sûr que vous interpréter les résultats de vos tests correctement. Comment testez-vous, exactement?

oid devrait déjà encapsuler toutes les informations requises, même dans le scénario «clients multiples» avec JIT et la mise en commun. La dernière fois que j'ai mis en place un tel écouteur d'événements (il a été un certain temps), en s'appuyant sur oid a bien fonctionné. Bien que, la majorité des composants dans mon environnement a été écrit en VB6 (par conséquent, vécu en STA). Pourtant, même avec STA, vous pouvez avoir plusieurs appels à différents stades d'exécution par un seul thread. Comme il existe une limite supérieure pour le nombre de threads dans le pool de threads COM + STA, vous pouvez avoir la situation suivante: appel A démarre sur un thread particulier, appel B démarre sur le même thread, appel B renvoie, appelle A renvoie. Je ne me souviens d'aucun problème de suivi des appels par oid sans "quelques informations supplémentaires sur l'appelant".

L'idée d'implémentation que vous considérez est, en général, canonique. COM+ spy L'exemple fourni avec Platform SDK utilise l'argument oid pour suivre les appels individuels. Vous pouvez trouver les sources de l'application dans <Path to SDK samples>\Samples\com\administration\spy. L'exemple utilise cette implémentation depuis un certain temps (depuis Windows 2003 au moins). Et aujourd'hui, ce sont des éons après MTA et même COM + introduction. S'il y avait des défauts, l'échantillon serait mis à jour à ce stade. Espérons.

+0

Merci d'avoir répondu. Tu avais raison de remettre en question mes tests. Je ne peux pas reproduire ce que j'ai vu plus tôt alors j'ai probablement fait une erreur stupide avant. Je pensais avoir vu un deuxième événement * call * pour un 'oid' avant l'événement' return' lors du premier appel. –

1

Le lien MSDN « Creating COM+ PerfMon Counters to Monitor COM+ Data » semble faire à peu près ce que vous visez (bien que dans C++ géré, je pense).

La partie pertinente est, je suppose:

void IComMethodEvents.OnMethodCall(ref COMSVCSEVENTINFO ei, ulong 
    lObjID, ref Guid gClsID, ref Guid gIID, uint nIndex) 
{ 
    //Make sure that monitoring is enabled and that our performance 
    //counter has been initialized. 
    if (Monitor && pcMethodDuration != null) 
    { 
    try 
    {      
     //We are going to store the initial value in a Sorted List 
     //collection. To do this we are going to need a key that 
     //represents this call. 
     string strKey = lObjID.ToString() + gClsID.ToString() + 
      gIID.ToString() + nIndex.ToString(); 

Cela pourrait être la solution à votre réfléchir sur les OID (lobjId dans leur exemple). Je ne sais pas si cela couvre votre scénario multi-utilisateur, vous devrez essayer. La page contient pas mal de détails sur le sujet, donc j'espère que vous serez en mesure de le comprendre. Bonne chance.

+1

Oui, c'était l'article auquel j'ai fait référence dans la mise à jour 3 de la question. Je crois que ça ne marchera pas comme ça. Ce qui serait vraiment sympa, c'est une documentation sur la raison pour laquelle l'interface IComMethod2Events a été ajoutée. Je pense qu'il est là pour résoudre les problèmes de corrélation dans un MTA mais je n'ai rien trouvé à ce sujet. –

+0

Ah, désolé - vous avez raison. :) Ma faute. Je n'ai aucune expérience avec cette interface donc je ne peux pas vous aider, mais je suggère de faire une simple application multi-thread et de tester l'approche ("Créer des compteurs COM + PerfMon ..."), pour voir si cela fonctionne comme prévu. Et à propos de ça? –

+0

Oui, je l'ai fait (encore) avec des résultats différents comme vous pouvez le voir dans un commentaire à l'autre réponse. Je dois avoir fait une erreur stupide la première fois que j'ai testé cela. Merci pour le temps que vous avez passé à répondre à ma question. –