Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

A Beginner's Tutorial for Understanding WCF Instance Management

4.83/5 (14 votes)
2 Apr 2013CPOL9 min read 34.4K   565  
This article discusses about the various ways of managing the WCF service class instances.

Introduction

In this article we will discuss about the various ways of managing the wcf service class instances. We will try to see all the possible ways of instance management and try to see each one using a sample application. We will also talk briefly about the pros and cons of each method and when could each technique be useful.

Background

So far we have discussed the basics of a WCF service and how to create a WCF service(A Beginner's Tutorial for Understanding Windows Communication Foundation (WCF)[^]). We have also looked at the various ways of hosting a WCF service(A Beginner's Tutorial on How to Host a WCF Service (IIS Hosting and Self Hosting)[^]) and how can the WCF faults and exceptions be handled(A Beginner's Tutorial for Understanding Exception Handling, FaultExceptions and FaultContracts in WCF[^]).

Now moving on with the discussion, from a WCF service developers perspective it is important to understand how the instances of our WCF service class is being created and how will it effect the overall service operations. WCF provides us the possibility of configuring the service behavior in terms of instance creation modes and understanding all the instance modes is really important to configure our WCF service to work in proper manner. So let us look at how the instance management for the WCF service works and how we can configure it as per our needs.

There are three possible ways of configuring WCF instances.

  1. PerCall
  2. PerSession
  3. Single

The PerCall mode says that this WCF service class instance will be created on every function call. These function calls could be from same client or different client. Whenever a function call is made from the client application a WCF service class instance is created, the function is called and the instance is disposed. Now if the same or any other client call the same or any other method of the service a new instance will be created and there is no way to reclaim the old instance.

The PerSession instance mode specifies that one instance of WCF service class will be created for each client. So if the client remains active and make multiple calls to the same or multiple methods of the service then the instance created for this particular client will be reused. Now this comes in very handy when we need to have some sequence of operations performed on the service and state of the service needs to be preserved between the calls.

The Single mode specifies that there will be only one instance for the WCF service class for all the clients. It is more like having a singleton class that will be used by all the clients.

Note: One important thing to note for the PerSession mode is that it has dependency on the protocol being used to access the service. If the service is being accessed via http i.e. basicHttpBinding then PerSession mode will not work because the http itself is stateless at the protocol level and thus the stateful configuration of PerSession will not work. In such cases, to have the stateful behavior, the service class will have to implement additional logic to save and reload the clients state across method calls.

To configure the instance mode we need to specify the ServiceBehavior attribute of the WCF service class implementation with the InstanceContextMode value. The value could be InstanceContextMode.PerCall, InstanceContextMode.PerSession and InstanceContextMode.Single respectively for the above mentioned modes. 

Using the code

Let is now try to see all these instance modes in action using a sample application. Let us first implement a simple WCF service which will expose a simple ServiceContract. We will use this service to test the instance modes.

Getting the Test Service Ready

C#
[ServiceContract]
public interface ISampleService
{
    [OperationContract]
    int TestFunction();
}

Now the implementation of this service contract will be fairly simple, we will keep a class member variable that will keep track of number of function calls and will let the caller know how many times the function has been called on that instance.

C#
public class SampleService : ISampleService
{
    int count = 0;

    public int TestFunction()
    {
        // Function called on this instance so let increment the instance variable
        count += 1;

        // Lets tell the called about the number of function calls he made
        return count;
    }
}

Note: We have not specified the InstanceContextMode right now but we will do that later. But if we don't specify any mode then the default value is PerSession.

Creating a Host

We will self host this service in a console application and expose the service via TCP. the reason for this is that we only would like to see the instance modes behavior in this sample and not deal with the protocol limitations. (Since hosting it over http would make PerSession mode not to work).

So we create the endpoint of the service as:

  • Address: net.tcp://localhost/TestService
  • Binding: netTcpBinding
  • Contract: SampleServiceNamespace.SampleService

And the code to host the service will look like:

C#
static void Main(string[] args)
{
    using (ServiceHost host = new ServiceHost(typeof(SampleServiceNamespace.SampleService)))
    {
        host.Open();

        Console.WriteLine("Service up and running at:");
        foreach (var ea in host.Description.Endpoints)
        {
            Console.WriteLine(ea.Address);
        }

        Console.ReadLine();
        host.Close();
    }
}

We can run the host to access our test service. We will then change the InstanceContextMode with all possible options and restart the host again to test the new behavior. Right now running the host will look like:

Image 1

Note: Please refer to the app.config file of the host application to see the full configuration. 

Creating the Test Client 

We will now create a simple test client which will call the function of the WCF service 5 times in a loop.

C#
static void Main(string[] args)
{
    using (ServiceReference1.SampleServiceClient client = new ServiceReference1.SampleServiceClient())
    {
        for (int i = 1; i <= 5; ++i)
        {
            Console.WriteLine
            (
                string.Format
                (
                    "Service called: {0} times, Return value: {1}",
                    i,
                    client.TestFunction()
                )
            );
        }
    }

    Console.ReadLine();
}

Now we have the required thing in place, let us now go and test all the instance modes one by one.

Testing PerCall

First thing we need to do is to set the InstanceContextMode of the service implantation class to PerCall.

C#
[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCall)]
public class SampleService : ISampleService
{
    int count = 0;

    public int TestFunction()
    {
        // Function called on this instance so let increment the instance variable
        count += 1;

        // Lets tell the called about the number of function calls he made
        return count;
    }
}

Now after starting the service host application, we will run our client. The output will look like:

Image 2

Now it is clear from the above output that for each call(even from the same client), a new instance of WCF service class is being created and thus value of 1 is being returned always.

Testing PerSession

First thing we need to do is to set the InstanceContextMode of the service implantation class to PerSession.

C#
[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)]
public class SampleService : ISampleService
{
    int count = 0;

    public int TestFunction()
    {
        // Function called on this instance so let increment the instance variable
        count += 1;

        // Lets tell the called about the number of function calls he made
        return count;
    }
}

Now after starting the service host application, we will run multiple instance of the client application. The reason for running the multiple instances is that each instance will have its own service proxy and independent session. The output will look like: 

Image 3

Now it is clear from the above output that for each client one instance of the WCF service class is being created. But for every client the state is being preserved and the same instance is being reused across function calls.

Testing Single

First thing we need to do is to set the InstanceContextMode of the service implantation class to Single.

C#
[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]
public class SampleService : ISampleService
{
    int count = 0;

    public int TestFunction()
    {
        // Function called on this instance so let increment the instance variable
        count += 1;

        // Lets tell the called about the number of function calls he made
        return count;
    }
}

Now after starting the service host application, we will again run multiple instance of the client application. The reason for running the multiple instances is that each instance will have its own service proxy and independent session. The output will look like:

Image 4

Now when the first client ran the instance of the WCF service class is created. All the further requests from the same client or from any other client were served from that instance only. This is the reason that the output shows values getting preserved and incremented not only across function calls but also across multiple clients.

So we saw how we can configure the WCF service instance modes to PerCall, PerSession and Single mode. using PerCall is recommended when our service is using some valuable resources like Connection objects, file streams. Using PerSession is recommended when our application need to access the service via a stateful protocol and the state needs to be preserved across multiple method calls. using Single is recommended when we only need one instance of our service class running irrespective of the number of clients.

A note on SessionMode 

In the service contract we can also specify a property for configuring SessionMode. This property specifies how the sessions will be created on client requests. We can use this property to take control over the session creation for our WCF services.

There are three possible values for this property.

  • Allowed
  • NotAllowed
  • Required
The Allowed option specifies that this service will accept request from both sessionful and sessionless clients. Having sessions is not mandatory but if the clients want to work in sessionful manner, it is allowed. This mode is the default mode for WCF services. 

The NotAllowed option specifies that the service will not work in sessionful mode i.e. it will only accept requests from the sessionless/stateless clients. In case any sessionful/stateful client tries to make a request, an exception will be thrown.

The Required option states that the service will only work in sessionful environment i.e. only sessionful/stateful clients can request the service operations. In case of stateless clients making any requests, an exception will be thrown. 

These modes are important because the resulting behavior of the the WCF service will depend on the options selected for InstanceContextMode in ServiceBehavior and SessionMode in ServiceContract. So these options must be set carefully with the desired behavior in mind.

Note: There are two more important and related concepts closely related with Instancing, one is how we can sepcify the order of operations in a sessionful service and other is the concurrency control for a WCF service. Details in these topics can be found in the following articles: 

Point of interest

In this article we saw what are the various ways of configuring the instance of a WCF service class. The InstanceContextMode plays a very important role when we need to have a stateful or singleton service behavior.

If we need to have states while using PerCall or we need our service to maintain state over a stateless protocol/binding then the service will have to implement its own logic for managing states(perhaps like serializing and de-serialzing the state on each method call). Also, over a stateful protocol, if we need the PerSession mode for our service then we also need to take care of the sequence of operations too. Both these topics need separate discussions and I have not included them in this article to keep this article free from digression. 

This has been written from a beginner's perspective but the reader should at least know the basics of WCF service and WCF hosting to get the full understanding of this article. I hope this has been informative.

History

  • 23 March 2013: First version.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)