Чтение онлайн

на главную - закладки

Жанры

Интернет-журнал "Домашняя лаборатория", 2007 №6
Шрифт:

_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 и его свойства LogicalCallID.

Если в данный момент не выполняется синхронный вызов, или новый вызов не является вложенным для исполняемого синхронного вызова, то начинается проверка вложенности нового вызова в один из исходящих асинхронных вызовов.

Поделиться:
Популярные книги

Жена фаворита королевы. Посмешище двора

Семина Дия
Фантастика:
фэнтези
5.00
рейтинг книги
Жена фаворита королевы. Посмешище двора

Новый Рал 8

Северный Лис
8. Рал!
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Новый Рал 8

Барон Дубов 2

Карелин Сергей Витальевич
2. Его Дубейшество
Фантастика:
юмористическое фэнтези
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Барон Дубов 2

Девочка для Генерала. Книга первая

Кистяева Марина
1. Любовь сильных мира сего
Любовные романы:
остросюжетные любовные романы
эро литература
4.67
рейтинг книги
Девочка для Генерала. Книга первая

Случайная жена для лорда Дракона

Волконская Оксана
Фантастика:
юмористическая фантастика
попаданцы
5.00
рейтинг книги
Случайная жена для лорда Дракона

Вампиры девичьих грез. Тетралогия. Город над бездной

Борисова Алина Александровна
Вампиры девичьих грез
Фантастика:
фэнтези
6.60
рейтинг книги
Вампиры девичьих грез. Тетралогия. Город над бездной

Демон

Парсиев Дмитрий
2. История одного эволюционера
Фантастика:
рпг
постапокалипсис
5.00
рейтинг книги
Демон

Темный Лекарь 7

Токсик Саша
7. Темный Лекарь
Фантастика:
попаданцы
аниме
фэнтези
5.75
рейтинг книги
Темный Лекарь 7

Вспомнить всё (сборник)

Дик Филип Киндред
Фантастика:
научная фантастика
6.00
рейтинг книги
Вспомнить всё (сборник)

Сумеречный Стрелок 10

Карелин Сергей Витальевич
10. Сумеречный стрелок
Фантастика:
рпг
аниме
фэнтези
5.00
рейтинг книги
Сумеречный Стрелок 10

Кодекс Охотника. Книга XXIII

Винокуров Юрий
23. Кодекс Охотника
Фантастика:
боевая фантастика
попаданцы
5.00
рейтинг книги
Кодекс Охотника. Книга XXIII

Никита Хрущев. Рождение сверхдержавы

Хрущев Сергей
2. Трилогия об отце
Документальная литература:
биографии и мемуары
5.00
рейтинг книги
Никита Хрущев. Рождение сверхдержавы

Камень. Книга 3

Минин Станислав
3. Камень
Фантастика:
фэнтези
боевая фантастика
8.58
рейтинг книги
Камень. Книга 3

Дворянская кровь

Седой Василий
1. Дворянская кровь
Фантастика:
попаданцы
альтернативная история
7.00
рейтинг книги
Дворянская кровь