Understand PerSession Behavior in WCF Services

This article helps you to understand PerSession Behavior in WCF Services, how to implement PerSession behavior and understand difference between PerCall and PerSession WCF services.


What happens when WCF service configured as Per Session ?

When client creates a new proxy of WCF service configured as InstanceContextMode=InstanceContextMode.PerSession, WCF service creates a dedicated instance for particular client proxy and handle all subsequent calls through this instance until client closes proxy. Each private session uniquely binds a proxy to particular instance. Note that the client session has one service instance per proxy. If the client creates another proxy to the same or a different service endpoint, then new proxy will have different dedicated instance.


As each instance maintains session in service memory, this behavior creates scalability and transaction issues like classic client-server model. With normal infrastrucre it is difficult to handle more than a dozen ongoing calls due to cost associated with each dedicated instance.

WCF supports three kind of behavior - PerCall, PerSession and Single. When you use bindings like wsHttpBinding which support reliable session, PerSession is default behavior. For more info on WCF service behavior see wcf service instance management by InstanceContextMode.


Implementing PerSession service Behavior


Create WCF Service for PerSession Behavior

Create a new WCF service library and client applications as suggested in create WCF service with PerCall Service Behavior. and understand how it works for PerCall behavior.

We will make some modification in WCF Service library to work it as PerSession.

You may give different names to projects.


Configure WCF Service for PerSession Behavior

Assuming that you have created a WCF Service Library and client application as suggested in previous step or download code files here. And hosted this WCF Service in IIS.

Open ProductService file from PerSessionWCFService WCF Service Library application. Modify ServiceBehavior attribute to configure PerSession.

Your code will look like

                
    [ServiceBehavior(Name = "ProductService",
         Namespace = "http://dotnetmentors.com/productservice",
        InstanceContextMode = InstanceContextMode.PerSession)]
    public class ProductService : IProductService
    {
        public void SetProductQty(int qty)
        {
            this.ProductQty = qty;
        }

        public int GetProductQty()
        {
            return this.ProductQty;
        }

        private int ProductQty
        {
            get;
            set;
        }
    }
            

Note that we have changed InstanceContextMode property and set it as PerSession. Even if you removed setting for InstanceContextMode property the default value PerSession will be applied as you are using binding with reliable session.


Update Service Reference

You have configured service as PerSession, now build service library, publish and host it in IIS.

Open client application and update existing Service Reference by right click on ProductServiceRef under Service References of client application. Select Update Service Reference


Client application for PerSession WCF Service

Open client application -> Program.cs file. Add code suggested in below descriptions to main method of Program.cs file.

                
    ProductServiceRef.ProductServiceClient client
        = new ProductServiceRef.ProductServiceClient();
                    
                

It creates a new client proxy for Product Service. WCF service will create new dedicated instance to handle this proxy. The data which is manipulated by this instace will be saved in memory for future reference. All request will be handle by this instance untill you call client.close();

                
    client.SetProductQty(10);
    Console.WriteLine(string.Format
                ("Current Product Qty: {0}", client.GetProductQty()));

    client.SetProductQty(20);
    Console.WriteLine(string.Format
                ("Current Product Qty: {0}", client.GetProductQty()));
    Console.WriteLine(string.Format
                ("Current Product Qty: {0}", client.GetProductQty()));

    client.Close();
                    
            

First line is calling OperationContract SetProductQty which takes input value as 10. At service side when this operation get called it save the value in private property ProductQty which is avilable for next calls.

Second line of code block calls OperationContract GetProductQty, service returns value which is saved in property ProductQty. In this case it returns value as 10. As this is PerSession behavior wcf service saved the value 10 to ProductQty. If this was PerCall service behavior you would have got 0 (integer default) for each read call.

Third line of code block again call operation to set value as 20. Next two lines read values from ProductQty and get it as 20.

The reason behind getting value as 20 for second read call is, the value of ProductQty as 20 will be retain as long as you do not call client.close() to close proxy.

Next line closes the current client proxy.

                                
    client = new ProductServiceRef.ProductServiceClient();
    Console.WriteLine(string.Format
                        ("Current Product Qty: {0}", client.GetProductQty()));
                    
            

Now you assign new service instance to client object and call operation contract to read value of ProductQty however you haven't set the value and previous proxy is closed you will be getting value as 0(integer default).

Your entire code block will look like this.

                
namespace ClientApp
{
   class Program
   {
    static void Main(string[] args)
    {
        ProductServiceRef.ProductServiceClient client
            = new ProductServiceRef.ProductServiceClient();

        client.SetProductQty(10);
        Console.WriteLine(string.Format
                    ("Current Product Qty: {0}", client.GetProductQty()));

        client.SetProductQty(20);
        Console.WriteLine(string.Format
                    ("Current Product Qty: {0}", client.GetProductQty()));
        Console.WriteLine(string.Format
                    ("Current Product Qty: {0}", client.GetProductQty()));

        client.Close();

        client = new ProductServiceRef.ProductServiceClient();
        Console.WriteLine(string.Format
                    ("Current Product Qty: {0}", client.GetProductQty()));
        client.Close(); 

        Console.Read();
    }
  }
}
         

Download source code.

Speak your mind :
Leave a comment for this article on dotnetbloogers.com