Корреляция IComMethodEvents

При реализации IComMethodEvents вы получаете три события.

  • OnMethodCall
  • OnMethodException
  • OnMethodReturn

Целью того, что я пытаюсь сделать, является регистрация времени вызова для каждого метода в компонентах COM +.

Время события может быть получено с помощью lTime и lMicroTime в структуре COMSVCSEVENTINFO, так что запустив это время как в OnMethodCall, так и в OnMethodReturn Я должен уметь вычислять время вызова, но как я могу быть уверен, что эти два события связаны.

При тестировании это выглядит так, как если бы я мог использовать активированный объект just-in-time (JIT) oid.

Любые проблемы при этом или другие способы?

Одной из проблем может быть то, что я вижу, что oid часто используется повторно, поэтому, если события по какой-либо причине выведены из строя, было бы немного сложнее реализовать корреляцию.

Обновление 1:

Дальнейшее тестирование показывает, что oid недостаточно для многопользовательского сценария. Один и тот же объект используется одновременно, поэтому корреляция должна выполняться с использованием, по меньшей мере, oid и original caller. Следующим вопросом будет вопрос: как получить оригинального звонящего от подписчика событий COM +?

Обновление 2:

Только что нашел IComMethod2Events. Разница в том, что события имеют идентификатор потока, выполняющего вызов. Выглядит многообещающе в тестах, и я не могу представить сценарий, где корреляция может потерпеть неудачу. Модель Threading для компонентов COM + Any Apartment.

Обновление 3

В этой статье Создание COM + PerfMon счетчиков для мониторинга COM + данных oid. Я не думаю, что этого достаточно в многопоточной квартире.

<суб > Примечание. В конечном итоге я введу это в Delphi, чтобы добавить тег Delphi. Я также добавил тег С#, потому что, скорее всего, язык, используемый для реализации интерфейса, вообще не важен. Обновление: предварительно добавив тег С++, чтобы привлечь внимание того, кто ранее использовал этот материал.

суб >

Ответ 1

... если события по какой-либо причине выведены из строя...

Они никогда не делают. Издатель системных событий COM + запускает эти события с помощью службы COM + Events. Вызов события синхронно с точки зрения издателя событий. Когда издатель запускает событие, он не переходит к следующему, пока все подписчики не завершат обработку инициированного события. Естественно, события OnMethodReturn/OnMethodException не публикуются перед сопоставлением OnMethodCall. Я вспоминаю чтение КБ относительно условий гонки/сломанных подписки в событиях COM+. Насколько мне известно, все эти ошибки были рассмотрены в различных пакетах обновлений для Windows 2000. Хотя, по общему признанию, я не стараюсь оставаться в курсе событий в этой области.

При реализации IComMethod2Events вы подписываетесь на ту же самую переходную подписку, что и на IComMethodEvents. Таким образом, порядок запущенных событий одинаковый.

... поэтому корреляция должна выполняться с использованием не менее oid и original caller...

На данный момент я действительно не уверен, правильно ли вы интерпретируете результаты своих тестов. Как вы точно протестируете?

oid должен уже инкапсулировать всю требуемую информацию, даже в сценарии "несколько клиентов" с JIT и пулом. В прошлый раз я реализовал такой прослушиватель событий (это было какое-то время), полагаясь на oid. Хотя большинство компонентов в моей среде было написано на VB6 (следовательно, они жили в STA). Тем не менее, даже с помощью STA вы можете иметь несколько вызовов на разных этапах выполнения одним потоком. Поскольку существует ограничение на количество потоков в пуле потоков COM + STA, вы можете иметь следующую ситуацию: вызов A запускается в определенном потоке, вызов B начинается в том же потоке, вызов B возвращается, вызов A возвращается. Я не помню никаких проблем с отслеживанием вызовов oid без "дополнительной информации о вызывающем".

Идея реализации, которую вы рассматриваете, является большой, канонической. COM+ spy образец, который поставляется с Platform SDK использует аргумент oid для отслеживания отдельных вызовов. Источники приложений можно найти в <Path to SDK samples>\Samples\com\administration\spy. Образец использует эту реализацию довольно долго (начиная с Windows 2003). И сегодня это эоны после внедрения MTA и даже COM+. Если есть недостатки, образец будет обновлен в этот момент. Будем надеяться.

Ответ 2

Ссылка MSDN " Создание счетчиков COM + PerfMon для мониторинга данных COM +" похоже, делает практически то, к чему вы стремитесь (хотя в управляемом С++ Я думаю).

Соответствующая часть - это, я думаю:

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();

Это может быть решением ваших размышлений о oid (lObjID в их примере). Не знаю, охватывает ли это ваш многопользовательский сценарий, вам придется попробовать. На странице есть довольно много деталей по этому вопросу, поэтому, надеюсь, вы сможете это выяснить. Удачи.