Как написать службу WCF с постоянным хранилищем в памяти?
Я написал службу WCF, но данные, хранящиеся в реализации Service, не сохраняются между вызовами, даже если они хранятся в статической переменной. Что я могу сделать?
Реализация службы выглядит следующим образом:
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();
}
Ответы
Ответ 1
По умолчанию для WCF instanceMode установлено значение "Вызов", то есть данные, используемые в службе, специфичны для этого клиента для этого вызова метода.
В своей реализации попробуйте добавить
[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single, ConcurrencyMode=ConcurrencyMode.Single)]
public class MyService: IService
Это делает сервис по существу одноэлементным.
Ответ 2
Что вам нужно сделать, это создать долговечный сервис:
WCF Долговечные услуги - это услуги WCF в которых операции могут запоминаться значения частных переменных (= состояние услуги) между перезапусками serivcehost и/или клиент.
Ответ 3
Вы хотите сохранить данные за пределами вашего экземпляра ServiceHost
? Если это так, то я согласен с тем, что долговременное обслуживание имеет смысл.
Однако, если вы только хотите сохранить данные между вызовами вашей службы WCF, пока служба жива, то долговременная услуга является излишней в моем скромном мнении. Использование статических данных вполне приемлемо; это то, что я делаю в своем проекте WCF. Фактически, код, который вы показали, должен работать, поэтому здесь происходит что-то еще.
Является ли метод Main()
фактическим, как вы его показали? Если это так, то это проблема. Как только ваше консольное приложение с поддержкой WCF запустится, он немедленно отключится, запустив с ним службу WCF. У вас должна быть некоторая логика, чтобы поддерживать консольное приложение, потому что служба WCF останется только "размещенной", пока консольное приложение запущено.
Если это не проблема, сообщите мне, и я добавлю полный код простого приложения, демонстрирующего, как это сделать.
Ответ 4
Добавить
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]
Выше вашего класса, и у вас будет служба, представляющая собой один экземпляр (т.е. пропуски класса остаются неизменными) и допускает несколько параллельных подключений.
Теперь вам нужно позаботиться о том, чтобы ваша собственность читала/записывала, т.е. использовала блокировки, как вы уже сделали (или какую-то другую технику).