- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
Интернет-журнал 'Домашняя лаборатория', 2007 №6 - Вязовский
Шрифт:
Интервал:
Закладка:
_property = prop;
_nextSink = nextSink
}
Каждый перехватчик должен обеспечить обработку как синхронных, так и асинхронных вызовов. Соответствующие методы объявлены в интерфейсе IMessageSink. Это SyncProcessMessage и AsyncProcessMessage.
В данном перехватчике обработка синхронных вызовов осуществляется следующим образом:
public virtual IMessage SyncProcessMessage(IMessage reqMsg) {
Workitem work = new Workitem(reqMsg,
_nextSink, null);
_property.HandleWorkRequest(work);
return work.ReplyMessage;
}
Собственно вызов в форме сообщения типа IMessage передается как единственный входной параметр. Возвращаемое значение (также типа IMessage) содержит результат, полученный данным перехватчиком от следующего в цепочки перехватчика после того, как вызов пройдет через всю цепочку перехватчиков до сервера, будет обработан на сервере, а ответ от него пройдет через всю цепочку перехватчиков в обратном направлении до данного перехватчика. Тут надо заметить, что на этом пути в каком-либо промежуточном перехватчике вызов может быть преобразован в асинхронную форму.
Роль данного перехватчика состоит в инкапсуляции вызова в объект типа WorkItem и его сохранении в очереди работ. Для этого вызывается конструктор WorkItem (reqMsg, _nextSink, null), первые два параметра которого задают вызов в форме сообщения и ссылку на следующий перехватчик. Третий параметр используется только в случае асинхронных вызовов. По умолчанию инкапсулирующая вызов работа work относится к синхронному типу.
После инкапсуляции вызова соответствующая работа передается свойству синхронизации:
_property.HandleWorkRequest(work);
Метод HandleWorkRequest класса SynchronizationAttribute ответственен за запись инкапсулированного вызова в очередь работ, за своевременное извлечение его из очереди и передачу следующему перехватчику, и, наконец, за получение ответа. Ответ доступен через свойство ReplyMessage работы, инкапсулирующей вызов. Значение этого свойства и возвращается как результат вызова метода SyncProcessMessage.
Как свойство синхронизации обрабатывает инкапсулированный синхронный вызов, полученный от перехватчика
Теперь временно прервем процесс изучение класса SynchronizedServerContextSink И рассмотрим метод HandleWorkRequest класса SynchronizationAttribute. Ниже приведена часть кода этого метода, которая относится к обработке именно синхронных вызовов:
internal virtual void HandleWorkRequest(WorkItem work) {
bool bQueued;
if (!IsNestedCall(work._reqMsg)) {
if (work.IsAsync()) {
…….
}
else {
lock(work) {
lock(_workItemQueue) {
if ((!_locked) &&
(_workltemQueue.Count == 0)) {
_locked = true;
bQueued = false;
}
else {
bQueued = true;
work.SetWaiting();
_workltemQueue.Enqueue(work);
}
}
if (bQueued == true) {
Monitor.Wait(work);
if (!worк. IsDummy()) {
DispatcherCallBack(null, true);
}
else {
lock(_workltemQueue) {
_workItemQueue.Dequeue();
}
}
}
else {
if (!worк. IsDummy()) {
work.SetSignaled();
ExecuteWorkltem(work);
HandleWorkCompletion();
}
}
}
}
}
else {
work.SetSignaled();
work.Execute();
}
}
Прежде всего выясняется — является ли инкапсулированный вызов work._reqMsg вложенным вызовом, т. е. вызовом, инициированным в процессе выполнения выполняемого в данный момент синхронного или исходящего асинхронного вызова:
if (!IsNestedCall(work._reqMsg)) {……..
Правила обработки вложенного вызова зависят от реентерабельности контекста синхронизации. Если контекст реентерабельный, то никакой специальной обработки вложенных вызовов производить не надо. В этом случае любой новый вызов (в том числе и вложенный) имеет право исполняться в реентерабельном контексте в то время, как выполняемый в данный момент вызов приостановлен на время ожидания ответа на какой-либо сделанный в его рамках внешний вызов.
Если же контекст синхронизации нереентерабельный, то никакой новый вызов не может выполняться в данном контексте, если в данном контексте в данное время выполняется какой-либо синхронный вызов. Если при выполнении синхронного вызова была инициирована цепочка вызовов и последний в этой цепочке вызов является вызовом в данный контекст синхронизации, то его блокировка приведет к блокировке всей очереди вызовов (текущий вызов никогда не завершится). Именно в связи с этим в случае нереентерабельного контекста синхронизации и синхронного исполняемого вызова вложенный вызов должен исполняться вне очереди.
Рассмотрим определенный В ЭТОМ же классе SynchronizationAttribute метод IsNestedCall.
internal bool IsNestedCall(IMessage reqMsg) {
bool bNested = false;
if (!IsReEntrant) {
String lcid = SyncCallOutLCID;
if (lcid!= null) {
LogicalCallContext callCtx =
(LogicalCallContext)
reqMsg.Properties[Mes sage.CallContextKey];
if (callCtx!=null &&
lcid.Equals(callCtx.RemotingData.LogicalCalllD)) {
bNested = true;
}
}
if (IbNested && AsyncCallOutLCIDList.Count>0) {
LogicalCallContext callCtx =
(LogicalCallContext)
reqMsg.Properties[Message.CallContextKey];
if (AsyncCallOutLCIDList.Contains(
callCtx.RemotingData.LogicalCalllD)) {
bNested = true;
}
}
}
return bNested;
}
Этот метод возвращает true если текущий контекст (точнее, текущий домен синхронизации) нереентерабельный, а новый вызов (reqMsg) является вложенным для исполняемого в данный момент синхронного вызова, или для одного из исходящих асинхронных вызовов. Во всех остальных случаях возвращается false.
Вначале выясняется синхронность выполняемого в данный момент вызова:
String lcid = SyncCallOutLCID;
if (lcid!= null) {
......
}
Свойство SyncCallOutLCID атрибута синхронизации возвращает идентификатор логического вызова исполняемого в данный момент вызова, если этот вызов синхронный. В противном случае возвращается null.
Теперь в случае синхронности исполняемого вызова мы получаем доступ к контексту вызова для вызова reqMsg:
LogicalCallContext callCtx =
(LogicalCallContext)
reqMsg.Properties[Message.CallContextKey];
Надо заметить, что тут имеется ввиду класс Message из пространства имен System.Runtime.Remoting.Messaging. Реализация такого класса в этом пространстве имен имеется в Rotor, но отсутствует в .NET. Статическое поле CallContextKey равно __CallContext.
Если доступ к контексту вызова получен, то проверяется, что идентификатор логического вызова исполняемого в данный момент синхронного вызова lcid совпадает с идентификатором логического вызова для вызова reqMsg. В случае их совпадения флаг вложенности bNested получает значение true:
if (callCtx!=null &&
lcid.Equals(callCtx.RemotingData.LogicalCalllD)) {
bNested = true;
}
Здесь ОПЯТЬ приходится отметить, что в .NET у класса LogicalCallContext нет свойства RemotingData типа CallContextRemotingData, нет и самого класса CallContextRemotingData и

