Выбрать главу

                 reqMsg.Properties[Message.CallContextKey];

      String lcid = Identity.GetNewLogicalCallID();

      cctx.RemotingData.LogicalCalllD = lcid;

      _property.AsynCallOutLCIDList.Add(lcid);

}

Зачем вообще сохраняется список идентификаторов исходящих асинхронных вызовов? И почему он обновляется только для нереентерабельного случая?

Единственно, для чего этот список необходим (и именно в случае нереентерабельного контекста) — для определения того, является ли новый входящий вызов вложенным (см. код методов IsNestedCall и HandleWorkRequest). При изложении этого вопроса ранее уже отмечалось наличие некоторых проблем, связанных с определение понятия вложенного вызова и его использования.

Теперь пора отправить исходящий асинхронный вызов следующему перехватчику исходящих асинхронных вызовов. И тут мы должны указать, куда посылать уведомления о завершении вызова. Непосредственно использовать перехватчик уведомлений replySink, предоставленный вызывающей стороной, нельзя, т. к. его непосредственное использование может нарушить логику синхронизации, поддерживаемую в домене синхронизации. В связи с этим создается специальный перехватчик уведомлений mySink, который придерживается логики синхронизации и обеспечивает безопасную работу с replySink:

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.

10. Дэвид С. Платт. Знакомство с Microsoft.NET. Microsoft Press. Русская редакция. 2001

11. David Chappel. Exploring Kerberos, the Protocol for Distributed Security in Windows 2000. Microsoft System Journal, August 1999.

12. David Chappel. Microsoft Message Queue Is a Fast, Efficient Choice for Your Distributed Applications. Microsoft System Journal, July 1998.

13. COM+ Programmer's Guide. Microsoft Press, 2000.

14. А.Новик. Система поддержки событий в СОМ+. Технология клиент-сервер, 1999'4, www.optim.ru.

15. Tom Armstrong. СОМ+ Events. Visual C++ Developers Journal, July/August, 1999.

16. Jeff Prosise. A Hands-On Look at COM+ Events. Visual C++ Developers Journal, July/August, January/February 2000.

17. Tom Archer. Inside C#. Microsoft Press,2001

18. David Stuts, Ted Neward, Geoff Shilling. Shared Source CLI Essentials. Глава 1 (Introducing the CLI Component Model), Глава 3 (Using Types to Describe Components), Глава 4 (Extracting Types from Assemblies) и глава 7 (Managing Memory within the Execution Engine).

http://www.oreilly.com/catalog/sscliess

19. [SOP1] W.Harrison, H.Ossher. Subject-oriented programing (A critique of pure objects). In Proceedings of the 8th Conference on Object-Oriented Programming, Systems, Languages, and Applications (OOPSLA'93), ACM SIGPLAN Notices, Vol.28, no.10, 1993, pp.411-428

20. [SOP2] Hompage of the Subject-Oriented Programming Project, IBM Thomas J.Watson Research Center, Yorktown Heights, New York, http://www.research.ibm.com/sop

21. [CF1] M.Aksit, A.Tripathi. Data Astraction Mechanisms in Sina/ST. In Proceedings of the Conference on Object-Oriented Programming, Systems, Languages, and Applications (OOPSLA’88), ACM SIGPLAN Notices. Vol. 23, no. 11, 1988, pp.265-275

22. [CF2] Homepage of the TRESE Project, University of the Twente, The Netherlands, http: //wwwtrese. cs. utwente. nl

23. [API] K.Leiberherr. Component Enhancement: An Adaptive Reusability Mechanism for Groups of Collaborating Classes. In Information Processing'92, 12th World Computer Congress, Madrid, Spain, J. van Leeuwen (Ed.), Elsevier, 1992, pp.179-185

24. [API] Homepage of the Demeter Project.Northeastern University, Boston, Massachusetts, http://www.ccs.neu.edu/research/demeter

25. [AOP1] Gregor Kiezales, Sohn Lamping, Anurag Mendhekar, Chris Maeda, Cristina Videira Lopes, Jean-Marc Loingtier, John Irwin. Aspect-Oriented Programming. In Proceedings of the European Conference on Object-Oriented Programming (ECOOP'97). Finland, Springer Verlag, INCS 1241, June 1997

26. [AOP2] K.Czamecki. Generative Programming: Principles and Techniques of Software Engineering Based on Automated Configuration and Fragment-Based Component Models. PhD thesis, Technische Universitat Ilmenau, Germany, 1998. (Глава Aspect-Oriented Decomposition and Composition)

27. [AOP3] Dharma Shkla, Simon Fell, Chris Sells. Aspect-Oriented Programming Enables Better Code Encapsulation and Reuse. MSDN Magazine, March 2002.

28. http://www.msdn.microsoft.com

29. http://www.dotsite.spb.ru

СПРАВОЧНИК

Англо-русский словарь компьютерной лексики

И. Н. Мизинина, А. И. Мизинина, И. В. Жильцов

А

А1. основной дисковод для дискет; 2. шестнадцатиричная цифра с десятичным значением 10