Шрифт:
AsyncReplySink mySink =
new AsyncReplySink(replySink, _property);
Класс AsyncReplySink будет рассмотрен чуть позже.
И вот, наконец, исходящий асинхронный вызов reqMsg передается следующему перехватчику исходящих асинхронных вызовов, а для получения уведомления указывается mySink:
msgCtrl = _nextSink.AsyncProcessMessage (
reqMsg,
(IMessageSink)mySink);
return msgCtrl;
Теперь рассмотрим класс AsyncReplySink:
internal class AsyncReplySink: IMessageSink {
…..
}
В конструкторе в полях _nextSink и _property сохраняются соответственно ссылка на следующий перехватчик (в нашем случае это будет replySink) и ссылка на свойство синхронизации
internal AsyncReplySink(IMessageSink nextsink,
SynchronizationAttribute prop) {
_nextSink = nextSink;
_property = prop;
}
Как и в любом перехватчике, основными методами являются SyncProcessMessage и AsyncProcessMessage.
Вот код для обработки уведомлений, полученных в виде синхронного вызова:
public virtual IMessage SyncProcessMessage (
IMessage reqMsg) {
Workltem work = new WorkItem (
reqMsg,
_nextSink,
null);
_property.HandieWorkRequest(work);
if (!_property.IsReEntrant) {
_property.AsyncCallOutLCIDList.Remove(
((LogicalCallContext)
reqMsg.Properties[Message.
CallContextKey]).
RemotingData.LogicalCallID);
}
return work.ReplyMessage;
}
Мы не можем сразу же послать уведомление на обработку в перехватчик replySink, так как не уверены в том, что он не нарушит логики синхронизации. В связи с этим мы инкапсулируем уведомление в работу
Workltem work = new WorkItem (
reqMsg,
_nextSink,
null);
и обрабатываем его как обычную новую работу, инкапсулирующию синхронный вызов:
_property.HandieWorkRequest(work);
В зависимости от ситуации эта работа будет поставлена в очередь или будет выполняться без задержек, но в любом случае логика синхронизации не будет нарушена. Здесь наш поток блокируется до завершения обработки работы work (включая время простоя в очереди).
По завершении ее обработки удаляем соответствующий идентификатор из списка исходящих асинхронных вызовов (только в случае нереентерабельного контекста) и возвращаем результат:
if (!_property.IsReEntrant) {
_property.AsyncCallOutLCIDList.Remove(
((LogicalCallContext)
reqMsg.Properties[Message.
CallContextKey]).
RemotingData.LogicalCalllD);
}
return work.ReplyMessage;
Завершаем рассмотрением метода AsyncProcessMessage. Здесь все просто. Полагается, что уведомления о завершении асинхронных вызовов не должны посылаться в виде асинхронных вызовов. В связи с этим данный метод просто вызывает исключение NotSupportedExeption:
public virtual IMessageCtrl AsyncProcessMessage (
IMessage reqMsg,
IMessageSink replySink) {
throw new NotSupportedException;
}
Литература
1. Роберт Орфали, Дан Харки, Джери Эдвардс. Основы CORBA. М., 1999.
2. Дейл Роджерсон. Основы COM. Microsoft Corporation. 1997. </li>
3. Эндрю Трельсен. Модель СОМ и применение ATL 3.0. 2001.
4. Guy Eddon, Henry Eddon. Inside COM+ Base Services. Microsoft Press, 1999.
5. Эш Рофейл, Яссер Шохауд. СОМ и СОМ+. Полное руководство., М., 2000.
6. Дональд Бокс. Сущность технологии СОМ. СПб, 2001.
7. Роберт Дж. Оберг. СОМ+. Технология, основы и программирование. Практическое руководство по Windows 2000 DNA. М., 2000.
8. Microsoft.NET Framwork SDK Documentation.
9. David S.Platt. Understanding COM+.Microsoft Press,1999.