Постоянство данных WCF между сессиями - PullRequest
3 голосов
/ 09 ноября 2008

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

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

Ответы [ 4 ]

4 голосов
/ 10 января 2009

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

3 голосов
/ 10 января 2009

Один из вариантов - использовать статические члены, как сказал Джимми МакНалти. У меня есть служба 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 () происходит внутри своего собственного экземпляра службы, и каждый экземпляр имеет доступ к статической коллекции. Поскольку каждый экземпляр службы работает в отдельном потоке, доступ к коллекции должен быть синхронизирован.

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

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

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

Однако из всего, что я прочитал, PerCall выглядит более гибким.

Вы можете перейти по этой ссылке для различий между ними.

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

0 голосов
/ 09 ноября 2008

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

0 голосов
/ 09 ноября 2008

Возможно, кеширующая структура вроде скорость поможет вам.

...