Книга: 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"));
}

Такой контекст вызова может использоваться для отправки информации о пользователе, имени клиентской системы или просто как уникальный идентификатор, который применяется на серверной стороне для получения из базы данных некоторой информации о состоянии.

Оглавление книги


Генерация: 6.148. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз