Throttling In WCF: Concurrent Instance and Session - Part Two

In this article, you will learn about concurrent instance and session, using throttling in WCF.

Introduction

In this article, we will concentrate on the concurrent call and concurrent session. I have already covered concurrent call in my previous article. Please refer to the link, given below, regarding the same:

Pre-requisites

Pre-requisites

Note: Once again, I will request my readers to have brief knowledge of WCF before reading this article for better and accurate understanding.

Concurrent Instance

WCF concurrent Instance helps us to configure how WCF Service instance will serve  multiple requests at the same time. As we are aware, when we host our Service, it can get “n” number of calls.

We have three ways of WCF instancing.

Per Call

Every client request will get the new instance. It’s a default mode. This instance will be disposed of after the response is sent back to the client.

Per Call

Now, I am showing you, how to implement this instance.

Step 1: My Service Contract

In my service contract, I have defined one method, which will return the instance count.

  1. namespace ConcurrentInstance  
  2. {  
  3.     // NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService1" in both code and config file together.  
  4.     [ServiceContract]  
  5.     public interface IMyInterface  
  6.     {  
  7.   
  8.         [OperationContract]  
  9.         int GetUpdatedObjectCount();  
  10.   
  11.         
  12.     }  
Step 2: Service Code
  1. [ServiceBehavior (InstanceContextMode=InstanceContextMode.PerCall)]  
  2.     public class MyService : IMyInterface  
  3.     {  
  4.          public int counter = 0;  
  5.         public int GetUpdatedObjectCount()  
  6.         {  
  7.             counter++;  
  8.             return counter;  
  9.         }  
  10.     }  
Step 3: Client Code 
  1. ServiceReference1.MyInterfaceClient objClient = new ServiceReference1.MyInterfaceClient();  
  2. //ConcerentMode.MyInterfaceClient objClient1 = new ConcerentMode.MyInterfaceClient();    
  3. //ConcerentMode.MyInterfaceClient objClient2 = new ConcerentMode.MyInterfaceClient();    
  4. //ConcerentMode.MyInterfaceClient objClient3 = new ConcerentMode.MyInterfaceClient();    
  5. Console.WriteLine("Counter Value : " + objClient.GetUpdatedObjectCount());  
  6. Console.WriteLine("Counter Value : " + objClient.GetUpdatedObjectCount());  
  7. Console.WriteLine("Counter Value : " + objClient.GetUpdatedObjectCount());  
  8. Console.WriteLine("Counter Value : " + objClient.GetUpdatedObjectCount());  
  9. Console.ReadLine();  
Output

Output

Per Session

In this mode, a session gets created b/w Client and Server. Thus, for the same instance (Object), we will get an updated counter value. I am referring to the same example.

Per Session

Now, I am showing you how to implement this instance.

Step 1: My Service Contract

In my service contract, I have defined one method, which will return the instance count.
  1. namespace ConcurrentInstance  
  2. {  
  3.     // NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService1" in both code and config file together.  
  4.     [ServiceContract]  
  5.     public interface IMyInterface  
  6.     {  
  7.   
  8.         [OperationContract]  
  9.         int GetUpdatedObjectCount();  
  10.   
  11.         
  12.     }  
Step 2: Service Code
  1. [ServiceBehavior (InstanceContextMode=InstanceContextMode.PerSession)]  
  2.     public class MyService : IMyInterface  
  3.     {  
  4.         public int counter;  
  5.   
  6.         public int GetUpdatedObjectCount()  
  7.         {  
  8.             counter++;  
  9.             return counter;  
  10.         }  
  11.     }  
Step 3: Client Code
  1. class Program  
  2.     {  
  3.         static void Main(string[] args)  
  4.         {  
  5.             ServiceReference1.MyInterfaceClient objClient = new ServiceReference1.MyInterfaceClient();  
  6.             ServiceReference1.MyInterfaceClient objClient1 = new ServiceReference1.MyInterfaceClient();  
  7.             //ConcerentMode.MyInterfaceClient objClient1 = new ConcerentMode.MyInterfaceClient();  
  8.             //ConcerentMode.MyInterfaceClient objClient2 = new ConcerentMode.MyInterfaceClient();  
  9.             //ConcerentMode.MyInterfaceClient objClient3 = new ConcerentMode.MyInterfaceClient();  
  10.               
  11.             Console.WriteLine("Counter Value : " + objClient.GetUpdatedObjectCount().ToString());  
  12.             Console.WriteLine("Counter Value : " + objClient.GetUpdatedObjectCount().ToString());  
  13.             Console.WriteLine("Counter Value : " + objClient1.GetUpdatedObjectCount().ToString());  
  14.             Console.WriteLine("Counter Value : " + objClient1.GetUpdatedObjectCount().ToString());  
  15.             Console.ReadLine();  
  16.              
  17.   
  18.   
  19.         }  
  20.     }  
Output

Output

Single

In this mode, all clients will be connected with the single object. Every time you create a new object, it will refer to the same old one. We can say only single instance will be created and later get disposed of.

Single

Now, I am showing you how to implement this instance.

Step 1: My Service Contract

In my service contract, I have defined one method, which will return the instance count.
  1. namespace ConcurrentInstance  
  2. {  
  3.     // NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService1" in both code and config file together.  
  4.     [ServiceContract]  
  5.     public interface IMyInterface  
  6.     {  
  7.   
  8.         [OperationContract]  
  9.         int GetUpdatedObjectCount();  
  10.    }    
Step 2: Service Code
  1. [ServiceBehavior (InstanceContextMode=InstanceContextMode.Single)]  
  2.     public class MyService : IMyInterface  
  3.     {  
  4.          int counter;  
  5.   
  6.         public int GetUpdatedObjectCount()  
  7.         {  
  8.             counter++;  
  9.             return counter;  
  10.         }  
  11.     }  
Step 3: Client Code
  1. class Program  
  2.     {  
  3.         static void Main(string[] args)  
  4.         {  
  5.             ServiceReference1.MyInterfaceClient objClient = new ServiceReference1.MyInterfaceClient();  
  6.             ServiceReference1.MyInterfaceClient objClient1 = new ServiceReference1.MyInterfaceClient();  
  7.   
  8.             Console.WriteLine("With Instance 1:");  
  9.             Console.WriteLine("Counter Value : " + objClient.GetUpdatedObjectCount().ToString());  
  10.             Console.WriteLine("Counter Value : " + objClient.GetUpdatedObjectCount().ToString());  
  11.   
  12.             Console.WriteLine("With Instance 2:");  
  13.             Console.WriteLine("Counter Value : " + objClient1.GetUpdatedObjectCount().ToString());  
  14.             Console.WriteLine("Counter Value : " + objClient1.GetUpdatedObjectCount().ToString());  
  15.             Console.ReadLine();  
  16.         }  
  17.     }  
Output

Output
 

Attribute Description
maxConcurrentInstances It refers to the max number of instances that get executed at one time. The default value is 26.

Web.Config Setting

  1. <behaviors>  
  2.       <serviceBehaviors>  
  3.         <behavior name="MyBehavior">  
  4.           <serviceMetadata httpGetEnabled="true"/>  
  5.           <serviceDebug includeExceptionDetailInFaults="true "/>            
  6. maxConcurrentInstances ="100"   
  7.         </behavior>  
  8.       </serviceBehaviors>  
  9.     </behaviors>  
Concurrent Sessions

According to MS, The MaxConcurrentSessions property specifies the maximum number of sessions a ServiceHost object can accept. Each listener object can have one pending channel session that does not count against the value of MaxConcurrentSessions until WCF accepts the channel session and begins processing messages on it. This property is most useful in scenarios that make use of sessions.

When this property is set to a value less than the number of client threads, the requests from the multiple clients may be queued in the same socket connection. The requests from the client, which have not created a session with the service, will be blocked until the service closes its session with the other clients; if the number of the open sessions on the service has reached MaxConcurrentSessions. The client requests which are not served get timed out and the service closes the session abruptly.

To avoid this situation, run the client threads from the different app domains. Thus, the request messages go into the different socket connections.

Web.Config Setting
  1. <behaviors>  
  2.       <serviceBehaviors>  
  3.         <behavior name="MyBehavior">  
  4.           <serviceMetadata httpGetEnabled="true"/>  
  5.           <serviceDebug includeExceptionDetailInFaults="true "/>            
  6. maxConcurrentSessions ="200"  
  7.         </behavior>  
  8.       </serviceBehaviors>  
  9.     </behaviors>  
Conclusion

In this article, we learned about different types of the concurrency calls, the concurrency session and also how to implement the same in Web.Config file. You can set the same in the code as well. It’s always recommended to set the same in config file, every time you need to compile the code and deploy it.