- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
Интернет-журнал 'Домашняя лаборатория', 2007 №6 - Вязовский
Шрифт:
Интервал:
Закладка:
Результаты
Ниже приведен вывод на консоль сервера. Видно, что сервер получил информацию о том, что клиентское приложение было запущено Администратором.
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, с помощью которого можно

