Симон Робинсон - C# для профессионалов. Том II
Контексты вызова
Активированные клиентом объекты могут сохранять состояние для определенного клиента. Для активированных клиентом объектов на сервере требуются ресурсы. Для активированных сервером объектов SingleCall новый экземпляр создается для каждого вызова экземпляра и никакие ресурсы не удерживаются на сервере, эти объекты не могут хранить состояние для клиента. Для управления состоянием можно держать состояние на клиентском стороне, данные о состоянии этого объекта посылаются с каждым вызовом метода на сервер. Для передачи состояния не требуется изменять сигнатуры всех методов с целью включения дополнительного параметра, так как можно использовать контексты вызова.
Контекст вызова перемещается вместе с логическим потоком выполнения и передается с каждым вызовом метода. Логический поток выполнения запускается из вызывающего потока выполнения и перемещается через все вызовы методов, которые запускаются из вызывающего потока выполнения и передаются через различные контексты, различные домены приложений и различные процессы.
Можно присвоить данные контексту вызова с помощью метода CallContext.SetData(). Класс с объекта, который используется в качестве данных для метода SetData(), должен реализовать интерфейс ILogicalThreadAffinative. Эти данные можно получить снова в том же логическом потоке выполнения (но, возможно, в другом физического потоке выполнения) с помощью CallContext.GetData().
Для данных контекста вызова здесь создается новая библиотека классов C# с вновь созданным классом CallContextData. Этот класс будет использоваться для передачи некоторых данных от клиента серверу с каждым вызовом метода. Класс, который передается с контекстом вызова, должен реализовать интерфейс System.Runtime.Remoting.Messaging.ILogicalThreadAffinative. Этот интерфейс не имеет метода, это просто отметка для среды выполнения, определяющая, что экземпляры этого класса перемещаются вместе с логическим потока выполнения. Класс CallContextData также помечается атрибутом Serializable, чтобы он мог передаваться по каналу:
using System;
using System.Runtime.Remoting.Messaging
namespace Wrox.ProfessionalCSharp {
[Serializable]
public class CallContextData : ILogicalThreadAffinative {
public CallContextData() { }
public string Data {
get {
return data;
}
set {
data = value;
}
}
protected string data;
}
}
В классе Hello метод Greeting() изменяется так, чтобы можно было получить доступ к контексту вызова. Для использования класса CallContextData необходимо сослаться на созданную ранее сборку CallContextData.dll. Чтобы работать с классом CallContext, должно быть открыто пространство имен System.Runtime.Remoting.Messaging:
public string Greeting(string name) {
Console.WriteLine("Greeting started");
CallContextData cookie = (CallContextData)CallContext.GetData("mycookie");
if (cookie ! = null) {
Console.WriteLine("Cookie: " + cookie.Data);
}
Console.WriteLine("Greeting finished");
return "Hello, " + name;
}
В клиентском коде передается информация контекста вызова:
CallContextData cookie = new CallContextData();
cookie.Data = "information for the server";
CallContext.SetData("mycookie", cookie);
for (int i=0; i< 5; i++) {
Console.WriteLine(obj.Greeting("Christian"));
}
Такой контекст вызова может использоваться для отправки информации о пользователе, имени клиентской системы или просто как уникальный идентификатор, который применяется на серверной стороне для получения из базы данных некоторой информации о состоянии.
Заключение
В этой главе мы видели, что .NET Remoting использовать очень легко. Удаленный объект должен просто наследовать из объекта MarshalByRefObject. В серверном приложении требуется только один метод для загрузки конфигурационного файла, чтобы настроить и запустить каналы и удаленные объекты. На клиенте загружается конфигурационный файл и используется оператор new для создания экземпляра удаленного объекта.
Также не слишком много работы требуется и в случаях, когда конфигурационные файлы не используются. На сервере создается канал и регистрируется удаленный объект. На клиенте делается канал и используется удаленный объект.
Наравне с этими приемами применяют много механизмов из других частей .NET Framework, которые также работают с .NET Remoting, такие как вызов асинхронных методов, выполнение обратных вызовов с помощью ключевых слов delegate и event и т. д.
Таким образом, использование .NET Remoting является очень простым, архитектура достаточно гибкой и по желанию расширяемой. Можно использовать каналы HTTP и TCP, которые также расширяются, или написать новые каналы с самого начала. Существуют форматтер SOAP и двоичный форматтер, но легко можно использовать свой собственный. Также имеется много точек перехвата, где возможно добавление в классы специальной функциональности, которая доставляется с помощью .NET Framework.
Глава 24
Службы Windows
В главе 22 рассматривается работа в сети, глава 23 охватывает работу с серверами с помощью .NET Remoting. Описанные серверные процессы запускаются вручную. Однако программы должны начинать работать автоматически во время запуска машины. Здесь на помощь приходят службы Windows.
В этой главе мы рассмотрим следующие вопросы:
□ Архитектура служб Windows, функциональность служебной программы, служебная управляющая программа, и служебная конфигурационная программа.
□ Реализация службы с помощью классов, находящихся в пространстве имен System.ServiceProcess.
□ Программы установки для конфигурирования службы в реестре.
□ Написание программы для управления службой с помощью класса ServiceController.
□ Реализация обработки событий. Так как службы обычно не имеют интерфейса пользователя, ошибки не могут выводиться в окне сообщений. Обработка событий является хорошим способом сообщения об ошибках.
□ Производительность службы. Мониторинг производительности может использоваться для получения информации о нормальном выполнении службы.
Вначале мы рассмотрим, что же такое службы.
Понятие службы
Службы Windows являются приложениями, которые начинают работать автоматически при запуске операционной системы. Они могут выполняться без интерактивного взаимодействия с пользователем системы. Можно сконфигурировать службу под требования специально сконфигурированным пользователем или таким пользователем System, который имеет больше привилегий, чем системный администратор.
Службы не выполняются на Windows 98 или Windows ME. Для них требуется ядро NT. Службы Windows работают в Windows NT 4, Windows 2000 и Windows ХР.
Вот несколько примеров таких служб:
□ Простая служба TCP/IP является служебной программой, которая содержит несколько небольших серверов TCP/IP: echo, daytime, quote и других.
□ Служба публикации в Web является службой Информационного сервера Интернета (IIS).
□ Журнал событий является службой для регистрации сообщений в системе регистрации событий.
□ Microsoft Search является службой, которая создает индексы данных на диске.
Можно использовать административную утилиту Component Services (Службы компонентов) для просмотра всех служб в системе. В Windows 2000 Server эта программа доступна через Start|Programs|Administrative Tools|Services:
Архитектура
Три типа программ требуются для работы службы. Служебная программа предназначена для решения реальной проблемы, в ней необходимо закодировать реальную функциональность. С помощью служебной управляющей программы можно посылать службе управляющие запросы, такие как запуск, останов, пауза и продолжение. И последнее, но не менее важное — требуется конфигурационная программа службы, с помощью которой можно установить службу. Это означает, что она не только копируется в файловую систему, но записывается также в реестр и конфигурируется как служба. В то время как компоненты .NET можно устанавливать, делая хсору, так как им не требуется реестр, установке служб необходима конфигурация в реестре. Программа конфигурации службы может также использоваться для последующего изменения конфигурации службы.
Служебная программа
Прежде чем рассматривать реализацию службы в .NET, давайте выясним, на что похожа архитектура служб в Windows и какова внутренняя функциональность службы.
Служебная программа реализует функциональность службы. Ей требуются три части: основная функция (точка входа программы), основная служебная функция и обработчик. Service Control Manager (SCM) играет очень важную роль для служб, он посылает запросы службе для ее запуска и останова. В служебной программе необходимо регистрировать точки входа службы в SCM, чтобы SCM мог вызывать эти точки входа в службе.