4

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

CSharped
  • 1,247
  • 4
  • 20
  • 49
  • 1
    Is there a reason you are using singletons? That seems to be an extremly ill-suited pattern in your architecture. Without singletons and using some proper debugging, you should be fine. – nvoigt Nov 15 '14 at 11:11

3 Answers3

0

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.

nvoigt
  • 75,013
  • 26
  • 93
  • 142
  • Thanks @nvoigt, that helped me understand better, is there any tool i mean some kind of memory profiling tool to understand/visualize what objects are in memory what objects are not during and after the service call – CSharped Nov 15 '14 at 11:28
  • @CSharped You can try some of the profilers mentioned [here](http://stackoverflow.com/questions/3927/what-are-some-good-net-profilers). – nvoigt Nov 15 '14 at 11:36
0

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.

usr
  • 168,620
  • 35
  • 240
  • 369
  • Thanks @usr, that helped me understand better, is there any tool i mean some kind of memory profiling tool to understand/visualize what objects are in memory what objects are not during and after the service call – CSharped Nov 15 '14 at 11:28
  • I believe Jetbrains memory profiler has a snapshot difference tool. But it will not show you objects that are alive but defunct (disposed, misconfigured, ...). I think manual inspection is the way to go here. Audit all static variables. – usr Nov 15 '14 at 11:51
0

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

  • Thanks, in my case I have a static variable causing all the trouble and which i now understand that will be stored in AppDomain of the the respective service, if my code is reinitialising that static variable will the variable take the new value? Can you help me understand how it works – CSharped Nov 16 '14 at 17:14