Problems with the singleton model in the WCF service method


I will go ahead and preface this by saying: I am somewhat new to WCF.

I'm working on a server-side routine that's responsible for doing a great deal of business logic. It's accessible from a client via WCF.

My main WCF method calls off to several other private methods. Instead of passing around all of the "lookup data" I need for the business logic to each private method, I decided to use a singleton instance of a class named DataProvider that contains all of this "lookup data".

At the end of the routine, I "release" the DataProvider's lookup data so the next time the routine is executed, the latest lookup data will be used.

So, here's a simplified example:

 public void Generate()
           //populate singleton DataProvider with it's lookup data...

           //do business logic...
           //release provider's lookup data...

This works great until I have two different clients that execute the method at (or near) the same time. Problems occur because they share the same singleton instance and the task who finishes first will release the DataProvider before the other completes.


What are my options here?

I'd like to avoid passing around all of the lookup data so the singleton pattern (or some derivative) seems like a good choice. I also need to be able to support multiple clients calling the method at the same time.

I believe the WCF service is configured as "Per-Call". I'm not sure if there's a way to configure a WCF service so that the static memory is not shared between service invocations.

Any help would be appreciated.

By default WCF is using "Per-Call", which means new instance of the WCF service is created for each client's call. Now since you implemented singleton even though new instance of the WCF is created it still calls your singleton.

If you would like to create lookup that is created for each call (like you have now) you should not do it as singleton. This way each client that calls your method will have new instance of the lookup, I think that was your intention.

However if you have lookup that is not changing that fast, I would recommend to share it between all calls, this will improve performance of your WCF service. You will need to declare your WCF service as

InstanceContextMode = InstanceContextMode.Single
ConcurrencyMode = ConcurrencyMode.Multiple

What this does is creating Singleton automatically for you by WCF, so you don't have to do it yourself, second it will support > 1 concurrent user (ConcurrencyMode.Multiple).

Now if you have your lookup that is changing and it needs to be reloaded after some period of time, I still would recommend using

InstanceContextMode = InstanceContextMode.Single
ConcurrencyMode = ConcurrencyMode.Multiple

but inside in your code cache it and then expire your cache at specific time or relative time (1 hours).

Here are some links that might help you: 3 ways to do WCF instance management (Per call, Per session and Single)

Hope this will help.