Reputation: 47
I have a WebService, which owns a Singleton:
public class WebService
{
private static Singleton _singleton = Singleton.Instance;
public void DoSomeJob(object jobObj) {
_singleton.QueueJob(jobObj);
}
}
.. and the Singleton, which should be threadsafe.
public static Singleton Instance
{
get
{
lock (_syncRoot)
{
if (_instance == null)
_instance = new Singleton();
return _instance;
}
}
}
}
What I was going to achieve this way is, that every client calling my WebService gives its object to the same instance of the singleton. This singleton again, does not really do more than queueing the object and processing it when a timer ticks.
The problem I was facing (and still am), is that the Singleton is getting killed every time the WebService terminates. However, I am not sure if this is happening because the owner of the Singleton is being destructed or for some reason given by the app pool settings. I have tried to make the app pool "always running" and "suspending" when idle, instead of "on demand" and "terminate" - no success :-/
Why is the Singleton getting killed off each time? How can I keep the Singleton's instance alive between WebService executions?
Upvotes: 2
Views: 1093
Reputation: 31750
Why is the Singleton getting killed off each time?
You need to understand about how WCF manages service instancing to understand why this is. By default WCF will create a new service instance per client over a session-enabled binding, or per call if no session is supported.
This means that the service instance which is dispached to handle a client call will load an instance of your singleton into memory. However, when either the the client session, or individual call (where no session is supported) has finished, the instance is unloaded, which means your singleton will also get unloded.
How can I keep the Singleton's instance alive between WebService executions?
There are two ways to do this:
InstanceContextMode=InstanceContxtMode.Single
in your service implementation declaration. Of the two options I would go with option 1. This is because singleton service instances are generally an anti-pattern because they do not scale, and should only be used when there is no alternative.
....considered to implement the queueing functionality to an external component, e.g. a windows service, but for the purpose of simplicity and reduced complexity I would like to implement that within the WebService
OK, right there is where I think the source of your problem is. There is a common belief around ditributed systems, which can be stated as the following:
I would modify that belief to:
In my opinion your decision to embed your timer/queueing requirement into your web service automatically makes your component complex.
I think breaking out the component which reads from the queue into another component is exactly what you need to do!
If this is daunting to you, then I would very strongly recommend using topshelf to manage your windows service, which is a free framework which makes the creation and deployment of services very simple.
Upvotes: 1