Как написать сервис WCF с постоянным хранилищем в памяти? - PullRequest
16 голосов
/ 01 декабря 2009

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

Реализация сервиса выглядит следующим образом:

public class Storage : IStorage
{
    protected static object[] _data;

    #region IStorage Members

    public void Insert(object[] data)
    {
        lock (_data)
        {
             _data = _data.Concat(data).ToArray();
        }
    }

    public object[] SelectAll()
    {
        lock (_data)
        {
            return (object[])_data.Clone();
        }
    }

    #endregion
}

Хост службы - это консольное приложение:

static void Main(string[] args)
{
    ServiceHost serviceHost =
       new ServiceHost(typeof(TimeSpanStorage));
    serviceHost.Open();
    Console.WriteLine("Service running.  Please 'Enter' to exit...");
    Console.ReadLine();
}

Ответы [ 4 ]

18 голосов
/ 01 декабря 2009

По умолчанию для экземпляра WCFModeMode установлено значение «За вызов», что означает, что данные, используемые в службе, являются специфическими для этого клиента для этого вызова метода.

В вашей реализации попробуйте добавить

[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single, ConcurrencyMode=ConcurrencyMode.Single)]
public class MyService: IService

Это делает сервис по сути одноразовым.

8 голосов
/ 01 декабря 2009

Что вы хотите сделать, это создать надежный сервис :

WCF. Услуги длительного пользования - это услуги WCF. в котором операции могут помнить значения частных переменных (= состояние службы) между перезапуски serivcehost и / или клиент.

3 голосов
/ 01 декабря 2009

Желаете ли вы сохранить данные после жизненного цикла вашего экземпляра ServiceHost? Если так, то я согласен, что долговременное обслуживание имеет смысл.

Однако, если вы хотите сохранять данные только между вызовами к вашей службе WCF , пока служба активна , то, по моему скромному мнению, надежная служба излишня. Использование статических данных вполне приемлемо; это именно то, что я делаю в своем проекте WCF. На самом деле код, который вы показали , должен работать, поэтому здесь происходит что-то еще.

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

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

0 голосов
/ 13 декабря 2010

Добавить:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]

Над вашим классом и у вас будет служба, представляющая собой один экземпляр (т. Е. Свойства класса остаются неизменными) и допускающая несколько одновременных соединений.

Теперь вы должны позаботиться о чтении / записи вашего свойства, то есть использовать блокировки, как вы уже сделали (или какой-то другой метод).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...