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

ЖАНРЫ

ЯЗЫК ПРОГРАММИРОВАНИЯ С# 2005 И ПЛАТФОРМА .NET 2.0. 3-е издание

Троелсен Эндрю

Шрифт:

Console.WriteLine("Создание поставщика Car");

Console.WriteLine("с помощью пользовательского конструктора');

theJBCars.AddRange(theCars);

 }

 …

}

Чтобы позволить вызывающей стороне активизировать CarProvider с помощью нового конструктора, нужно построить приложение сервера, которое зарегистрирует CarProvider, как САО-тип, а не как WKO-тип. Это можно сделать программно с помощью метода, аналогичного RemotingConfiguration.RegisterActivatedServiceType, или с помощью файла *.config на стороне сервера. Чтобы "жестко" задать

имя CAO-объекта в программном коде сервера, передайте информацию типа или типов (после создания и регистрации канала), как предлагается ниже.

// "Жёсткое" указание того, что CarProvider является САО-типом.

RemotingConfiguration.RegisterActivatedServiceType(typeof(CAOCarGeneralAsm.CarProvider));

Если вы предпочтете использовать файл *.config, вместо элемента ‹wellknown› используйте элемент ‹activated›, как показано ниже.

‹configuration›

 ‹system.runtime.remoting›

‹application›

‹service›

‹activated type = "CAOCarGeneralAsm.CarProvider, CAOCarGeneralAsm"/›

‹/service›

‹channels›

‹channel ref="tcp" port="32496" /›

/channels›

‹/application›

 ‹/system.runtime.remoting›

‹/configuration›

Наконец, нужно обновить приложение клиента, и не только с целью учета соответствующего файла *.config (или программных изменений в базовом коде) для запроса доступа к удаленному САО-объекту, но и с тем, чтобы вызвать созданный пользовательский конструктор типа CarProvider. Вот как должен выглядеть модифицированный метод Main на стороне клиента.

static void Main(string[] args) {

 // Чтение обновленного файла *.config.

 RemotingConfiguration.Configure("CAOCarProviderClient.exe.config");

 // Создание массива типов для передачи поставщику.

 JamesBondCar[] cars = {

new JamesBondCar ("Viper", 100, true, false),

new JamesBondCar("Shaken", 100, false, true),

new JamesВоndCar("Stirred", 100, true, true)

 };

 // Теперь вызов пользовательского конструктора.

 CarProvider ср = new CarProvider(cars);

 …

}

Обновленный файл *.сonfig клиента также должен использовать элемент ‹activated›, а не элемент ‹wellknown›. Кроме того, свойство url элемента ‹client› теперь должно указывать адрес зарегистрированного САО-объекта. Напомним, что при регистрации типа CarProvider сервером в виде WKO-объекта, клиент указывал соответствующую информацию в рамках элемента ‹wellknown›.

‹configuration›

 ‹system.runtime.remoting›

‹application›

‹client displayName = "CarClient" url = "tcp://localhost:32469"›

‹activated type="CAOCarGeneralAsm.CarProvider, CAOCarGeneralAsm" /›

‹/client›

‹channels›

‹channel ref="tcp"/›

‹/channels›

‹/application›

 ‹/system.runtime.remoting›

‹/configuration›

Чтобы "жестко"

запрограммировать запрос САО-типа клиентом, можете использовать метод RegistrationServices.RegisterActivatedClientType, как показано ниже.

static void Main(string[] args) {

 // Использование "жестких" значений.

 RemotingConfiguration.RegisterActivatedClientType(typeof(CAOCarGeneralAsm.CarProvider), "tcp://localhost:32469");

}

Запустив на выполнение обновленные компоновочные блоки сервера и клиента, вы с удовлетворением обнаружите, что можете передать свой пользовательский массив типов JamesBondCar удаленному объекту CarProvider через перегруженный конструктор.

Исходный код. Проекты CAOCarGeneralAsm, CAOCarProviderServer и CAOCarProviderCIient размещены в подкаталоге, соответствующем главе 18.

Схема лизингового управления циклом существования САО-типов и WKO-синглетов

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

С другой стороны, САО-типы, а также WKO-типы, сконфигурированные для активизации в виде синглета, являются по своей природе объектами, кумулятивно изменяющими параметры своего состояния в процессе выполнения вызовов клиентов. Учитывая эти две доступные опции установки конфигурации, возникает следующий вопрос: как процесс сервера "узнает" о том, что пора уничтожить такой MBR-объект? Если сборщик мусора на сервере уничтожит MBR-объекты, находящиеся в использовании удаленным клиентом, это создаст проблемы, А если серверу придется ожидать освобождения MBR-типов слишком долго, это отрицательно повлияет на работу системы, особенно если соответствующие MBR-объекты удерживают важные ресурсы (связь с базой данных, неуправляемые типы или какие-то другие ресурсы).

Цикл существования MBR-объекта, являющегося CAO-типом или WKD-синглетом, контролируется по схеме лизингового управления, которая тесно связана с процессом сборки мусора .NET. Если "время аренды" MBR-объекта, являющегося CAO типом или WKO-синглетом истекает, объект становится кандидатом на участие в очередном цикле сборки мусора. Как и в случае любого другого .NET-типа, если удаленный объект переопределяет System.Object.Finalize (с помощью синтаксиса деструктора C#), то среда выполнения .NET автоматически запустит соответствующую логику финализации.

Схема лизингового управления, используемая по умолчанию

Для MBR-объектов, являющихся САО-типами или WKO-синглетами, применяется так называемый лизинг по умолчанию, время которого равно пяти минутам. Если среда выполнения обнаружит, что MBR-объект, являющийся САО-типом или WKO-синглетом, остается неактивным в течение пяти минут, делается вывод о том, что клиент больше не использует данный удаленный объект, и поэтому этот объект может использоваться в процессе сборки мусора. При этом совсем не обязательно, чтобы после истечения времени лизинга объект помечался для сборки мусора немедленно. На самом деле есть много возможностей влиять на поведение, задаваемое лизингом по умолчанию.

Поделиться с друзьями: