KnigkinDom.org» » »📕 Интернет-журнал "Домашняя лаборатория", 2007 №6 - Усманов

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

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

1 ... 248 249 250 251 252 253 254 255 256 ... 361
Перейти на страницу:

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
вызов.

Результаты

Ниже приведен вывод на консоль сервера. Видно, что сервер получил информацию о том, что клиентское приложение было запущено Администратором.

Server is listening

UserName = Администратор

Bye

А вот и вывод на консоль клиента:

5 is sent to MyServer, Version=0.0.0.0, Culture=neutral,

PublicKeyToken=null

Total = 5

Bye

Возвращаемся к классу Workltem

Конструктор

Конструктор в качестве входных параметров принимает вызов в форме сообщения (reqMsg), ссылку на следующий перехватчик, которому будет переадресован данный вызов после того, как он отстоит всю очередь (nextSink) и ссылку на перехватчик для результатов асинхронного вызова (replySink). В случае синхронного вызова последний параметр задается равным null.

Ниже приведен код конструктора:

internal Workltem(IMessage reqMsg, IMessageSink nextSink,

        IMessageSink replySink) {

        _reqMsg = reqMsg;

        _replyMsg = null;

        _nextSink = nextsink;

        _replySink = replySink;

        _ctx = Thread.CurrentContext;

        _callCtx = CallContext.GetLogicalCallContext();

      }

Судя по приведенному коду, этот конструктор вызывается в том контексте, в котором в последствии будет выполняться вызов, инкапсулируемый в данный момент в экземпляр класса WorkItem. Об этом говорят строки, в которых присваиваются значения полям ctx и _callContext. Вызов Thread.CurrentContext возвращает текущий контекст (ссылку на экземпляр класса Context), а вызов CallContext.GetLogicalCallContext возвращает контекст логического вызова (ссылку на экземпляр класса LogicalCallCcontext), соответствующие текущим контексту и потоку. Здесь следует отметить, что в .NET Framework класс CallContext не реализует метод GetLogicalCallContext.

Итак, конструктор класса WorkItem должен вызываться в перехватчике, ассоциированном со свойством синхронизации, и этот перехватчик должен выполняться в том контексте и в потоке с таким контекстом вызова, в котором и с которым будет выполняться сам перехваченный вызов.

Флаги

В течении своей жизни работа, представляющая некоторый вызов, может находиться в одном из нескольких состояний. Эти состояния задаются наборами флагов:

private const int FLG_WAITING = 0x0001;

private const int FLG_SIGNALED = 0x0002;

private const int FLG_ASYNC = 0x0004;

private const int FLG_DUMMY = 0x0008;

Флаг FLGg_WAITING означает, что работа поставлена в очередь, флаг FLG_SIGNALED указывает на то, что первая в очереди работа начинает исполняться, флаг FLG_ASUNC помечает асинхронные работы (работы, представляющие асинхронные вызовы), и, наконец, флаг FLG_DUMMY помечает работу-заглушку. Этот флаг помечает фиктивную работу,

формируемую для представления результата внешнего вызова, сделанного при выполнении текущего вызова. Подробнее об этом будет говориться далее.

Текущая комбинация флагов сохраняется в поле internal int flags, для задания и чтения которого используются следующие методы:

internal virtual void SetWaiting() {

     _flags |= FLG_WAITING;

}

internal virtual bool IsWaiting() {

     return (_flags &FLG_WAITING) == FLG_WAITING;

}

internal virtual void SetSignaled() {

      _flags |= FLG_SIGNALED;

}

internal virtual bool IsSignaled() {

      return (_flags & FLG_SIGNALED) == FLG_SIGNALED;

}

internal virtual void SetAsync() {

      _flags |= FLG_ASYNC;

}

internal virtual bool IsAsync() {

      return (_flags & FLG_ASYNC) == FLG_ASYNC;

}

internal virtual void SetDummy() {

      _flags |= FLG_DUMMY;

}

internal virtual bool IsDummy() {

       return (_flags & FLG_DUMMY) == FLG_DUMMY;

}

Выполнение работы

Самый важный метод класса WorkItem — это метод Execute, обеспечивающий выполнение текущей работы. Этот метод вызывается в тот момент, когда подошла очередь выполнения этой работы.

internal virtual void Execute() {

      ContextTransitionFrame frame = new ContextTransitionFrame();

      Thread.CurrentThread.EnterContext(_ctx, ref frame);

      LogicalCallContext oldCallCtx =

           CallContext.SetLogicalCallContext(_callCtx);

       if (IsAsync()) {

           _nextSink.AsyncProcessMessage(_reqMsg, _replySink);

        }

        else if (_nextSink!= null) {

           _replyMsg = _nextSink.SyncProcessMessage(_reqMsg);

         }

        CallContext.SetLogicalCallContext(oldCallCtx);

        Thread.CurrentThread.ReturnToContext(ref frame);

}

Метод Execute может выполняться в различных контекстах и потоках, поэтому прежде всего нужно восстановить ту среду, в которой находился вызов в момент его перехвата и инкапсулирования в работу типа WorkItem.

Для этого формируется фрейм, сохраняющий некоторую информацию о переходе их одного контекста в другой контекст (эта информация позже используется для возвращения в контекст, в котором началось исполнение метода Execute) и выполняется переход из текущего контекста в контекст, сохраненный в поле ctx:

ContextTransitionFrame frame = new ContextTransitionFrame();

Thread.CurrentThread.EnterContext(_ctx, ref frame);

Отметим, что в .NET Framework нет класса ContextTransitionFrame, а в сигнатуре класса Thread нет метода EnterContext.

Далее сохраняется текущий контекст вызова в оldCаllСontехt, а с текущим потоком связывается тот контекст вызова, который был сохранен в поле _сallContext:

LogicalCallContext oldCallCtx =

       CallContext.SetLogicalCallContext(_callCtx);

К сожалениею, в сигнатуре класса CallContext в .NET Framework нет метода SetLogicalCallContext.

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

Интерфейс IMessageSink объявляет два метода, реализующие обработку соответственно синхронных и асинхронных вызовов. Это SyncProcessMessage И AsyncProcessMessage.

Таким образом, в зависимости от типа текущей работы (инкапсулированного в ней вызова), необходимо вызвать один из упомянутых вызовов на следующем перехватчике:

if (IsAsync()) {

        _nextSink.AsyncProcessMessage(_reqMsg, _replySink);

}

else if (_nextSink!= null) {

       _replyMsg = _nextSink.SyncProcessMessage(_reqMsg);

}

Вызов IsAsync возвращает true если текущая работа асинхронна. В этом случае на следующем перехватчике _nextSink вызывается AsyncProcessMessage и в качестве параметров передаются исходный вызов _reqMsg и ссылка на перехватчик для возвращения результата _replySink.

В случае синхронной работы вызывается SyncProcessMessage. Параметром является вызов, возвращаемое значение сохраняется в поле replyMsg.

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

И, наконец, текущий поток должен вернуться в старый контекст и связаться со старым контекстом вызова:

CallContext.SetLogicalCallContext(oldCallCtx);

Thread.CurrentThread.ReturnToContext(ref frame);

Завершая обсуждение класса WorkItem осталось упомянуть свойство ReplyMessage, с помощью которого можно

1 ... 248 249 250 251 252 253 254 255 256 ... 361
Перейти на страницу:
Отзывы - 0

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


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

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

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


Партнер

Новые отзывы

  1. Christine Christine26 июнь 01:23 ​​​​Сначала было тежеловта читать, но потом всё изменилось, я с удовольствием прочитала, спасибо за книгу. Я прочитала весь цикл... Опасное влечение - Полина Лоранс
  2. Тамаринда Тамаринда21 июнь 12:33 Редко что-то цепляет, но тут было всё живое, жизненное, чувственное, сильное, читайте, не пожалеете о своём времени...... Хрупкая связь - Ольга Джокер
  3. Гость Марина Гость Марина20 июнь 06:08 Книга очень понравилась, хотя и длинная. Героиня сильная личность. Да и герой не подкачал. ... Странная - Татьяна Александровна Шумкова
Все комметарии
Новое в блоге