views:

625

answers:

3

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 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();
}
+2  A: 

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.

Andrew Hare
thank you for your answer. I didn't found a memory persistence option within Durable services. Is there any? Or just database persistence options?
Jader Dias
+2  A: 

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.

MattC
Setting the context mode to `Single` is not necessarily the right thing to do - that will not allow per-transaction state. Using a `DurableOperation` is a much better choice.
Andrew Hare
I agree it wont allow the transactional control a Durable service does. And the singleton pattern defo has it's limits when you want to scale.The "data ... doesn't persists between calls" just made me think the OP was after something simple.
MattC
Setting the InstanceContextMode to Single is a horrible idea - your WCF service class is a singleton now, and either you have serialized the handling of all your requests (killing any performance), or you need to deal with multithreading issues (hard and error prone). THe best choice are durable services, which really simply store their state in a persistant store (a.k.a. a database).
marc_s
Again, I agree that would be the way to finally implement the service should it be required to be durable/performant. If you just want an array to stick around between calls while you play with WCF then that might be a bit heavy. OP didn't specify.
MattC
It worked in my tests. I don't care if it loses data when the service stops, so I don't have any complaints about this approach.
Jader Dias
Great but the other commenters are more relevent when the time comes to rework a prototype to a more solid system.
MattC
+1  A: 

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.

Matt Davis
No the Main method had a Console.ReadLine call. The question was edited to reflect this.
Jader Dias
What "while the service is alive" means? It means "while the service host console application is running" ?
Jader Dias
@Jader Dias: Yes, if you are only wanting to persist data while the `ServiceHost` console application is running, then there's no reason to use the durable service approach. The durable service approach will work, but so will the static data approach (again, that's what I'm using in my WCF service project).
Matt Davis
Thanks for the confirmation of my suspicions
Jader Dias