LoveRead.info » Книги » Разная литература » Интернет-журнал "Домашняя лаборатория", 2007 №6 - Вязовский

Интернет-журнал "Домашняя лаборатория", 2007 №6 - Вязовский

Книгу Интернет-журнал "Домашняя лаборатория", 2007 №6 - Вязовский читаем онлайн бесплатно полную версию! Чтобы начать читать не надо регистрации. Напомним, что читать онлайн вы можете не только на компьютере, но и на андроид (Android), iPhone и iPad. Приятного чтения!

138 0 18:00, 07-12-2022
Интернет-журнал "Домашняя лаборатория", 2007 №6 - Вязовский
07 декабрь 2022

Книга Интернет-журнал "Домашняя лаборатория", 2007 №6 - Вязовский читать онлайн бесплатно без регистрации

Большой и увлекательный, научно-прикладной и образовательный, но некоммерческий интернет-журнал, созданный группой энтузиастов. Интернет-журнал содержит материалы, найденные в Интернет или написанные для Интернет. Основная тематика статей — то, что можно сделать самому, от садовых поделок до сверхпроводников, но есть и просто полезные материалы.

    1 ... 254 255 256 257 258 259 260 261 262 ... 361
    Перейти на страницу:

          lock(_workltemQueue) {

                 _workItemQueue.Dequeue();

           }

    }

    Иными словами, фиктивная работа просто удаляется из очереди, после чего выполнение метода SyncProcessMessage завершается возвращением результата replyMsg и разбуженный поток продолжает выполнять основной вызов.

    Случай нереентерабельного контекста

    Теперь рассмотрим ветвь метода SyncProcessMessage класса SynchronizedClientContextSink, относящуюся к случаю нереентерабельного контекста:

    public virtual IMessage SyncProcessMessage (

           IMessage reqMsg) {

           IMessage replyMsg;

           if (_property.IsReEntrant) {

                 ……

            }

            else {

                 LogicalCallContext cctx =

                    (LogicalCallContext)

                        reqMsg.Properties[Message.CallContextKey];

                  String lcid = cctx.RemotingData.LogicalCalllD;

                  bool bClear = false;

                  if (lcid == null) {

                      lcid = Identity.GetNewLogicalCalllD ();

                      cctx.RemotingData.LogicalCalllD = lcid;

                      bClear = true;

                  }

                  bool bTopLevel=false;

                  if (_property.SyncCallOutLCID==null) {

                      _property.SyncCallOutLCID = lcid;

                      bTopLevel = true;

                   }

                   replyMsg = _nextSink.SyncProcessMessage(reqMsg);

                   if (bTopLevel) {

                       _property.SyncCallOutLCID = null;

                       if (bClear) {

                            LogicalCallContext cctxRet =

                                   (LogicalCallContext)

                                          replyMsg.Properties[Message.CallContextKey];

                            cctxRet.RemotingData.LogicalCalllD = null;

                              }

                       }

             }

               return replyMsg;

    }

    В нереентерабельном случае для предотвращения блокировок надо заботиться о первоочередном выполнении вновь поступающих вызовов, инициированных исполняемым в данный момент синхронным вызовом. Для этого используются уникальные идентификаторы, совпадающие у исходного синхронного вызова и всех инициированных им вызовов. При совпадении идентификатора нового вызова с идентификатором исполняемого вызова можно сделать заключение о том, что новый вызов инициирован исполняемым вызовом и должен выполняться без промедления. Итак, при отправлении синхронного вызова за пределы текущего контекста мы должны запомнить его идентификатор и быть готовыми незамедлительно обработать любой входящий вызов, если его идентификатор совпадает с идентификатором исходящего в данный момент вызова.

    Прежде всего нужно узнать идентификатор исходящего вызова. Для этого получаем доступ к его контексту вызова

    LogicalCallContext cctx =

         (LogicalCallContext)

                  reqMsg.Properties[Message.CallContextKey];

    и, затем, к самому идентификатору

    String lcid = cctx.RemotingData.LogicalCallID;

    Может оказаться, что в данный момент исходящий вызов (reqMsg) еще не имеет идентификатора. В таком случае присвоим ему новый еще не использованный идентификатор

    bool bClear = false;

    if (lcid == null) {

        lcid = Identity.GetNewLogicalCalllD();

        cctx.RemotingData.LogicalCalllD = lcid;

        bClear = true;

    }

    Здесь статический метод GetNewLogicalCallID класса Identity генерирует новый идентификатор, который и запоминается в контексте вызова.

    Если нам пришлось самим построить новый идентификатор для исходящего синхронного вызова, то его нужно и сохранить в свойстве синхронизации. В этом случае условное выражение в следующем операторе if равно true:

    bool bTopLevel=false;

    if (_property.SyncCallOutLCID==null) {

         _property.SyncCallOutLCID = lcid;

         bTopLevel = true;

    }

    Ну а теперь передаем исходящий вызов следующему перехватчику исходящих вызовов и ждем ответа

    replyMsg = _nextSink.SyncProcessMessage(reqMsg);

    Ну а теперь (после получения ответа) надо за собой почистить (если мы что-то поменяли в контексте вызова и в свойстве синхронизации):

    if (bTopLevel) {

        _property.SyncCallOutLCID = null;

        if (bClear) {

             LogicalCallContext cctxRet =

                  (LogicalCallContext)

                        replyMsg.Properties[Message.CallContextKey];

             cctxRet.RemotingData.LogicalCalllD = null;

          }

    }

    Здесь мы обнуляем свойство SyncCallOutLCID свойства синхронизации (если мы его только что сами установили) и обнуляем идентификатор для полученного ответа replyMsg (если мы сами задавали этот идентификатор для исходящего вызова).

    Перехват исходящих асинхронных вызовов

    Для обработки исходящих асинхронных вызовов перехватчик использует следующий код:

    public virtual IMessageCtrl AsyncProcessMessage(

          IMessage reqMsg,

          IMessageSink replySink) {

          IMessageCtrl msgCtrl = null;

          if (!_property.IsReEntrant) {

              LogicalCallContext cctx =

                    (LogicalCallContext)

                          reqMsg.Properties[Message.CallContextKey];

               String lcid = Identity.GetNewLogicalCalllD();

               cctx.RemotingData.LogicalCalllD = lcid;

               _property.AsyncCallOutLCIDList.Add(lcid);

           }

           AsyncReplySink mySink =

                new AsyncReplySink(replySink, _property);

            msgCtrl = _nextSink.AsyncProcessMessage (

                               reqMsg,

                               (IMessageSink)mySink);

           return msgCtrl;

    }

    В качестве входных параметров задаются сам вызов reqMsg и перехватчик, на который вызывающая сторона ожидает получения уведомления о завершении процесса выполнения асинхронного вызова.

    В случае нереентерабельного контекста исходящему асинхронному вызову назначается новый идентификатор и этот идентификатор сохраняется в списке _asyncLcidList исходящих асинхронных вызовов, поддерживаемому свойством синхронизации (доступ через свойство AsyncCallOutLCIDList). Заметим, что в случае асинхронных вызовов нет нужны сохранять один и тот же идентификатор по всей цепочке вызовов, в связи с чем здесь не проверяется наличие идентификатора, а сразу же назначается новый:

    if (!_property.IsReEntrant) {

         LogicalCallContext cctx =

               (LogicalCallContext)

                     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 {

    …..

    }

    В конструкторе

    1 ... 254 255 256 257 258 259 260 261 262 ... 361
    Перейти на страницу:
    1. Жалоба
    Отзывы - 0

    Прочитали книгу? Предлагаем вам поделится своим отзывом от прочитанного(прослушанного)! Ваш отзыв будет полезен читателям, которые еще только собираются познакомиться с произведением.


    Уважаемые читатели, слушатели и просто посетители нашей библиотеки! Просим Вас придерживаться определенных правил при комментировании литературных произведений.

    • 1. Просьба отказаться от дискриминационных высказываний. Мы защищаем право наших читателей свободно выражать свою точку зрения. Вместе с тем мы не терпим агрессии. На сайте запрещено оставлять комментарий, который содержит унизительные высказывания или призывы к насилию по отношению к отдельным лицам или группам людей на основании их расы, этнического происхождения, вероисповедания, недееспособности, пола, возраста, статуса ветерана, касты или сексуальной ориентации.
    • 2. Просьба отказаться от оскорблений, угроз и запугиваний.
    • 3. Просьба отказаться от нецензурной лексики.
    • 4. Просьба вести себя максимально корректно как по отношению к авторам, так и по отношению к другим читателям и их комментариям.

    Надеемся на Ваше понимание и благоразумие. С уважением, администратор LoveRead.info.


    Установить VPN и читай слушай бесплатно

    Новые отзывы

    1. Валентина Валентина04 июль 13:25 Большое спасибо за интересную тему.  Сюжет заманчиввй,интересный. Жду продолжения ... Лекарь Фамильяров. Том 7 - Александр Лиманский
    2. Наталья По Наталья По01 июль 10:12 Ужасный перевод:(... Аркадия - Эрин Дум
    3. Вика Вика29 июнь 21:56 Какая хрень с первых строк.  У ребенка в 14 месяце не может быть черепно мозговой травмы при падании с дивана ... Вернуть семью любой ценой - Чарли Ви
    Все комметарии
    Новинки бесплатной онлайн библиотеки