PerCall InstanceContextMode behaviour of WCF service

1.5k views Asked by At

I have a WCF service, exposing a ServiceContract with basicHttpBinding, so from my understanding InstanceContextMode will be set to PerCall (as basicHttpBinding doesn't support sessions) and ConcurrenyMode will be set to Single.

The client of this WCF is a windows service, which invokes 4 different operations on the service at the same time, within the service we have used a singleton class and there are few Static variables. We have been facing a problem where in a wrong value is getting passed to some of the DB Stored Procedures.

With PerCall InstanceContextMode and Single concurrency mode, i understand a new service instacne in created for every call and hence i am thinking that even though there are some singleton classes (we have not made it thread safe) in the service implementation and static variables all the objects will be destroyed, but we have observed running a SQL profiler that on old value is getting passed the DB.

We have written our WCF service code in a kind of 3-tier architecture, i mean ServiceClass, BusinessLogicLayer and DataAccessLayer, with PerCall set as instanceContextMode when we say the service instance is destroyed after the client request is finished, does it mean we destroy all the object in ServiceClass,BusinessLogicLayer and DataAccessLayer?

Pls help me understand what could be going wrong

3

There are 3 answers

1
Albin Abel On

Though it is restricted in any way static variables needs to be protected for thread safe as a best practice. Static variables will not be destroyed till the service is stopped / app pool recycle.

Using static variables for the data which changes are not recommended for distributed web farms, because those are not safer over a failover.

Visual Studio 2012 and above comes with a Memory profiler. But the simple thing can be done using a counter in the object constructors (only on testing) which can tell if there is a new instance created on every request or not.

   [ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCall,ConcurrencyMode=ConcurrencyMode.Single)]
public class TestServiceWithStaticVars : ITestServiceWithStaticVars
{
   static int instanceCount = 0;
    public TestServiceWithStaticVars()
    {
        Interlocked.Decrement(ref instanceCount);
    }
    public string GetInstanceCount()
    {
        return string.Format("You have created {0} instance", instanceCount);
    }

Let you know if better instance counter available to use with ease.

[Edit] as I can't comment now.

Re-assigning the static variable will take the new value as you said. The static variables are loaded in to HighFrequencyHeap for frequent access. For more information http://www.codeproject.com/Articles/15269/Static-Keyword-Demystified

2
nvoigt On

The InstanceContextMode PerCall means a new class of your service is instantiated per call. Static variables in your AppDomain will not be reset. They will stay between service calls, as long as your AppPool is not recycled.

Remove all statics including singletons from your code. They never belonged to your architecture anyway.

2
usr On

Many WCF requests share the same AppDomain. Static variables are per AppDomain. WCF does nothing to those variables (in fact it cannot even find out they exist). You are responsible for maintaining them.

WCF does not destroy any of your objects because neither does WCF understand what they mean nor does it know they exist.

The settings you mentioned are only relevant to the service object.

My usual advice regarding stateful server apps: You are working under bad practices here. You need to ensure thread-safety. In case the worker process shuts down (deployment, automatic restart, server reboot, app bug crashing the process, power loss, hardware failure, ...) your data is lost.