Шрифт:
}
обеспечивает выполнение повторных попыток открытия файла до тех пор, пока очередная такая попытка не увенчается успехом. Не смотря на то, что операции открытия и закрытия файла выполняются в рамках одной критической секции, в силу асинхронности этих операций открытие файла может произойти с некоторой задержкой после успешного выполнения команды закрытия файла.
4. Комментарий К коду класса MyCallTraceContextSink
? Данный внутренний класс реализует интерфейс IMessageSink и, следовательно, реализует некоторый перехватчик,
? Поле _nextsink будет хранить ссылку на следующий перехватчик в той цепи перехватчиков, в конец которой будет добавлен данный перехватчик,
? Поле _property предназначено для хранения ссылки на свойство контекста типа MyCallTraceAttribute. Перехватчик порождается благодаря методу GetPropertiesForNewContext, реализованного этим свойством контекста. Однако сейчас нам это свойство важно тем, что именно его метод LogMessage будет вызываться перехватчиком при перехвате нового вызова,
? Поле _replyMsg типа IMessage будет хранить ответ вызванного метода, полученный данным перехватчиком от перехватчика nextsink. о Конструктор данного класса принимает два аргумента:
— property
Это ссылка на свойство контекста, метод которого LogMessage будет вызываться данным перехватчиком.
— nextSink
Это ссылка на следующий перехватчик в цепи перехватчиков.
Данные значения присваиваются соответственно полям _property и _nextsink.
? Виртуальный метод SyncProcessMessage объявлен в интерфейсе IMessageSink. Этот метод реализует обработку синхронных вызовов, т. е. вызовов, после инициализации которых клиенты блокируются до получения ответа.
Единственный аргумент данного метода — сообщение reqMsg (request message), содержащее вызов, полученный от клиента и уже, возможно, обработанный перехватчиками, находящимися в цепочке ближе к клиенту.
Прежде всего выясняется тип полученного сообщения. Если это сообщение типа IMethodMessage, то это сообщение представляет собой именно вызов некоторого метода, который и должен перехватить наш перехватчик. При получении сообщения другого типа данный перехватчик пропускает его дальше без какой-либо обработки.
Обработка вызова состоит в том, что перехватчик выводит с помощью LogMessage информацию о типе, о методе и о входных ([IN]) аргументах. Пример (слегка отредактированный для удобства просмотра) выводимой информации в случае вызова метода Notify экземпляра класса News приведен ниже:
===SPbU.AOP_NET.News, MyServer, Version = 0.0.0.0,
Culture = neutral, PublicKeyToken = null
Notify
<<<IN>>> parameters: {
msg = new Account operation: +5)
}
В процессе обработки перехваченного вызова сообщение reqMsg приводится к типу IMethodMessage и блокируется свойство контекста _property. Эта блокировка позволит при записи информации в файл посредством вызова LogMessage группировать все строки, относящиеся к одному вызову, вместе, т. е. не допускать в файле с именем _logFileName чередования строк, относящихся к различным вызовам.
После завершения обработки перехваченного вызова данный перехватчик передает неизменное сообщение reqMsg следующему в цепочке перехватчику (перехватчику, находящемуся ближе к серверу). Для этого вызывается метод SyncProcessMessage перехватчика _nextSink.
После получения сообщения _replyMsg, содержащего ответ сервера (возможно обработанный перехватчиками, находящимися ближе к серверу), наш перехватчик в свою очередь обрабатывает это сообщение, если его тип есть IMethodReturnMessage. В процессе обработки полученное сообщение приводится к типу IMethodReturnMessage, после чего проверяется, не было ли в процессе выполнения данного вызова инициировано неперехваченное ранее исключение.
При наличии неперехваченного исключения на консоль сервера выводится соответствующее сообщение и метод возвращает полученный ответ без какой-либо обработки. В противном случае выполняется процесс, аналогичный описанному ранее (обработка вызова). Блокируется свойство контекста _property и посредством вызова метода _property.LogMessage выводится информация о типе, о вызванном методе, список выходных [out] аргументов. Ниже приведен пример для ответа на вызов метода Notify класса News: