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

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

Жанры

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

По завершении вызова метода Add клиент получает из свойства контекста значение свойства serverName, добавленное в контекст вызова сервером при выполнении Add. В результате клиент получает информацию о сборке, содержащей код сервера, выполнившего вызов.

Результаты

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

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.

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

Шведский стол

Ланцов Михаил Алексеевич
3. Сын Петра
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Шведский стол

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

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

Краш-тест для майора

Рам Янка
3. Серьёзные мальчики в форме
Любовные романы:
современные любовные романы
эро литература
6.25
рейтинг книги
Краш-тест для майора

Любовь Носорога

Зайцева Мария
Любовные романы:
современные любовные романы
9.11
рейтинг книги
Любовь Носорога

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

Токсик Саша
5. Темный Лекарь
Фантастика:
фэнтези
аниме
5.00
рейтинг книги
Темный Лекарь 5

Печать Пожирателя

Соломенный Илья
1. Пожиратель
Фантастика:
попаданцы
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Печать Пожирателя

Враг из прошлого тысячелетия

Еслер Андрей
4. Соприкосновение миров
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Враг из прошлого тысячелетия

Начальник милиции. Книга 5

Дамиров Рафаэль
5. Начальник милиции
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Начальник милиции. Книга 5

Возвышение Меркурия. Книга 16

Кронос Александр
16. Меркурий
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия. Книга 16

Метатель

Тарасов Ник
1. Метатель
Фантастика:
боевая фантастика
попаданцы
рпг
фэнтези
фантастика: прочее
постапокалипсис
5.00
рейтинг книги
Метатель

Запрети любить

Джейн Анна
1. Навсегда в моем сердце
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Запрети любить

На Ларэде

Кронос Александр
3. Лэрн
Фантастика:
фэнтези
героическая фантастика
стимпанк
5.00
рейтинг книги
На Ларэде

Третий. Том 4

INDIGO
Вселенная EVE Online
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
5.00
рейтинг книги
Третий. Том 4

Сочинения в трех томах. Том 1

Леблан Морис
Большая библиотека приключений и научной фантастики
Детективы:
классические детективы
5.00
рейтинг книги
Сочинения в трех томах. Том 1