метода, который клиент будет реализовывать в обработчике.

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

□ Удаленный объект должен также объявить экземпляр функции делегата, модифицированный ключевым словом event. Клиент будет использовать его для регистрации обработчика.

□ Клиент должен создать объект приемника с методом обработчика, имеющий такую же сигнатуру, как и определенный делегат, и должен зарегистрировать объект приемника для события на удаленном объекте.

Чтобы понять это, рассмотрим пример. Создадим пять классов для всех частей обработки событий в .NET Remoting. Класс Server является удаленным сервером, таким как один из тех, которые уже до этого встречались. Класс Server будет создавать канал на основе информации из конфигурационного файла и регистрировать удаленный объект, который реализуется в классе RemoteObject в удаленной среде выполнения. Удаленный объект объявляет аргументы делегата и порождает события в зарегистрированных функциях обработчика. Аргумент, который передается в функцию обработчика, имеет тип StatusEventArgs. Класс StatusEventArgs должен быть сериализуемым, поэтому его можно маршализовать клиенту.

Класс Client представляет клиентское приложение. Этот класс создает экземпляр класса EventSink и регистрирует метод StatusHandler() этого класса как обработчика для делегата в удаленном объекте. EventSink должен быть удаленным объектом, подобным классу RemoteClass, так как этот класс также будет вызываться через сеть.

Удаленный объект

Класс удаленного объекта реализуется в файле RemoteObject.cs. Класс удаленного объекта должен выводиться из MarshalByRefObject так, как было показано в предыдущих примерах. Чтобы сделать возможным для клиента регистрацию обработчика событий, который вызывается из удаленного объекта, необходимо объявить внешнюю функцию с помощью ключевого слова delegate. Мы объявляем делегата StatusEvent() с двумя аргументами: sender (поэтому клиент знает об объекте, который порождает событие) и переменную типа StatusEventArgs. В класс аргумента помещаем всю дополнительную информацию, которую необходимо послать клиенту.

Метод, который реализуется на стороне клиента, требует строгих ограничений. Он может иметь только входные параметры, возвращаемые типы, при этом параметры ref и out недопустимы; а типы аргументов должны быть либо [Serializable], либо удаленными (выводимыми из MarshalByRefObject):

public delegate void StatusEvent(object sender, StatusEventArgs e);

public class RemoteObject : MarshalByRefObject {

Внутри класса RemoteObject объявляется экземпляр функции делегата Status, модифицированный ключевым словом event. Клиент должен добавить обработчик событий в событие Status, чтобы получить статусную информацию из удаленного объекта:

public class RemoteObject : MarshalByRefObject {

 public RemoteObject() {

  Console.WriteLine('RemoteObject constructor called');

 }

 public event StatusEvent Status;

В методе LongWorking() проверяется, что обработчик событий регистрируется прежде, чем событие порождается с помощью Status(this, е). Чтобы удостовериться, что событие порождается асинхронно, мы получаем событие в начале метода перед выполнением Thread.Sleep() и после Sleep:

 public void LongWorking(int ms) {

  Console.WriteLine('RemoteObject: LongWorking() Started');

  StatusEventArgs e = new StatusEventArgs('Message for Client: LongWorking() Started');

  // породить событие

  if (Status != null) {

   Console.WriteLine('RemoteObject: Firing Starting Event');

   Status(this, e);

  }

  System.Threading.Thread.Sleep(ms);

  e.Message = 'Message for Client: LongWorking() Ending'; // породить событие окончания

  if (Status != null) {

   Console.WriteLine('RemoteObject: Firing Ending Event');

   Status(this, e);

  }

  Console.WriteLine('RemoteObject: LongWorking() Ending');

 }

}

Аргументы событий

Мы видели в классе RemoteObject, что класс StatusEventArgs используется как аргумент для делегата. С помощью атрибута [Serializable] экземпляр этого класса может передаваться от сервера клиенту. Мы используем простое свойство типа string для пересылки клиенту сообщения:

[Serializable]

public class StatusEventArgs {

 public StatusEventArgs(string m) {

  message = m;

 }

 public string Message {

  get {

   return message;

  }

  set {

   message = value;

  }

 }

 private string message;

}

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату