How to write a WCF service with in-memory persistent storage?
I wrote a WCF service, but the data stored in the Service implementation doesn't persists between calls, not even if stored in a static variable. What can I do?
The service implementation is as follows:
public class Storage : IStorage
{
protected static object[] _data;
#region 开发者_JS百科IStorage Members
public void Insert(object[] data)
{
lock (_data)
{
_data = _data.Concat(data).ToArray();
}
}
public object[] SelectAll()
{
lock (_data)
{
return (object[])_data.Clone();
}
}
#endregion
}
The service host is a console application:
static void Main(string[] args)
{
ServiceHost serviceHost =
new ServiceHost(typeof(TimeSpanStorage));
serviceHost.Open();
Console.WriteLine("Service running. Please 'Enter' to exit...");
Console.ReadLine();
}
By default WCF instanceMode is set to Per call, meaning data used in the service is specific to that client for that method call.
On your implementation try adding
[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single, ConcurrencyMode=ConcurrencyMode.Single)]
public class MyService: IService
This makes the service essentially a singleton.
What you are looking to do is create a durable service:
WCF Durable services are WCF services in which the operations can remember the values of private variables (=the state of the service) inbetween restarts of the serivcehost and/or client.
Are you wanting to persist the data beyond the lifetime of your ServiceHost
instance? If so, then I agree that a durable service makes sense.
However, if you are only wanting to persist data between calls to your WCF service while the service is alive, then a durable service is overkill in my humble opinion. Using static data is perfectly acceptable; it is precisely what I do in my WCF project. In fact, the code that you've shown should work, so something else is going on here.
Is the Main()
method actually as you've shown it? If so, then that's a problem. As soon as your WCF-enabled console application starts up, it immediately shuts back down, taking the WCF service with it. You need to have some logic in there to keep the console application alive because the WCF service will only remain 'hosted' while the console application is running.
If this is not the problem, let me know, and I'll add the full code of a simple application that demonstrates how to do this.
Add:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]
Above your class and you'll have a service that is a single instance (i.e. the class proterties remain the same) and allows multiple concurrent connections.
Now you have to take care of your property read/write, i.e. use locks as you've already done (or some other technique).
精彩评论