2008-11-09 3 views
3

Мы разрабатываем систему на основе WCF. В процессе мы пытаемся заблокировать некоторые данные от изменения несколькими пользователями. Таким образом, мы решили создать структуру данных, которая будет содержать необходимую информацию для выполнения логики блокировки (например, для хранения идентификатора заблокированных объектов)Сохранение данных WCF между сеансами

Проблема, с которой мы сталкиваемся, заключается в сохранении данных между сеансами. В любом случае мы можем избежать выполнения дорогостоящих вызовов базы данных? Я не уверен, как мы можем это сделать в WCF, поскольку он может сохранять данные (в памяти) только во время открытого сеанса.

ответ

0

Возможно, кэш-каркас, такой как velocity, поможет вам.

0

Создайте второй класс и установите его экземпляр InstanceContextMode в одиночном режиме и переместите все дорогостоящие методы там, а затем в вашем исходном классе используйте эти методы.

4

Статические члены класса, реализующего службу, совместно используются сеансами & вызовов.

3

Один из вариантов - использовать статические элементы, как сказал Джимми Макналти. У меня есть служба WCF, которая открывает сетевые подключения на основе указанного IP-адреса. Мой сервис настроен для режима экземпляра службы PerCall. В каждом сеансе я проверяю статическую структуру данных, чтобы узнать, открыто ли сетевое соединение для указанного IP-адреса. Вот пример.

[ServiceContract] 
public interface IMyService 
{ 
    [OperationContract] 
    void Start(IPAddress address); 
} 

[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCall)] 
public class MyService : IMyService 
{ 
    private static readonly List<IPAddress> _addresses = new List<IPAddress>(); 
    public void Start(IPAddress address) 
    { 
     lock(((ICollection)_addresses).SyncRoot) 
     { 
      if (!_addresses.Contains(address) 
      { 
       // Open the connection here and then store the address. 
       _addresses.Add(address); 
      } 
     } 
    } 
} 

Как настроен, каждый вызов Start() происходит в его собственном экземпляре службы, и каждый экземпляр имеет доступ к статической коллекции. Поскольку каждый экземпляр службы работает в отдельном потоке, доступ к коллекции должен быть синхронизирован.

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

Другим вариантом является использование режима экземпляра Single service, в отличие от режима экземпляра службы PerCall.

[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)] 
public class MyService : IMyService 
{ ... } 

Из всего, что я прочитал, PerCall кажется более гибким.

Вы можете следить за этим link за отличия между ними.

И не забывайте, что класс, который реализует ваш сервис, - это просто класс. Он работает, как и все классы C#. Вы можете добавить статический конструктор, свойства, обработчики событий, реализовать дополнительные интерфейсы и т. Д.

Смежные вопросы