Thursday, 11 June 2015

Concurrency mode in WCF - Single Concurrency Mode in WCF

This post require knowledge of Instance Context Mode in WCF. Please visit following post before reading this post.
http://logicsmaze.blogspot.in/2015/06/instance-context-mode-in-wcf.html

When multiple thread executing the application code simultaneously is called as concurrency.

There are 3 types of concurrency mode in WCF.

1. Single Concurrency Mode
2. Reentrant Concurrency Mode
3. Multiple Concurrency Mode

Concurrency mode can be set by using ConcurrencyMode attribute of [ServiceBehaviour]










The default concurrency mode in WCF is Single.This means only a single thread can access the service instance at any given point of time.An exclusive lock is acquired and all the other threads will have to wait until the current request completes and the lock is released.

Single Concurrency Mode in WCF :

A single request has access to the WCF service object at a given moment of time.So only one request will be proposed at a given moment of time.The other request have to wait  until the request processed by the WCF service is completed.

Whenever a WCF service handles client requests concurrently or not, depends on 3 things.

1.Service Instance Context mode
2. Service Concurrency Mode
3. Whether binding support session or not

Example 1 : If we set ConcurrencyMode Single and InstanceContextMode to PerCall, If used binding does not support session (basicHttpBinding does not support session) then service can processed concurrent call.

Example 2 : If we set ConcurrencyMode Single and InstanceContextMode to PerCall, If used binding support session (netTcpBinding support session) then service can not processed concurrent call.

[ServiceBehavior(ConcurrencyMode=ConcurrencyMode.Single,InstanceContextMode=InstanceContextMode.PerCall)]
   
Following table shows all the combination with Single concurrency mode to show when will concurrency call will processed and not.

Instance Context Mode Concurrency Mode Is Binding Support Session Will Concurrency Call Processed
PerCall Single No Yes
PerCall Single Yes No
PerSession Single No Yes
PerSession Single Yes Yes- Between different client
No-Requests from the same client
Single Single No No
Single Single Yes No
Code Implementation : following are the code implementation for example 1.

// Service Contract
[ServiceContract]
 public interface IService1
    {
        [OperationContract]
        List<int> GetEvenNumber();
        [OperationContract]
        List<int> GetOddNumber();

    }

//Service Implementation

[ServiceBehavior(ConcurrencyMode=ConcurrencyMode.Single,InstanceContextMode=InstanceContextMode.PerCall)]
    public class Service1 : IService1
    {

        public List<int> GetEvenNumber()
        {
            Console.WriteLine("Thread {0} Started GetEvenNumber at {1}", System.Threading.Thread.CurrentThread.ManagedThreadId, DateTime.Now);
            List<int> lstEvenNo = new List<int>();
            lstEvenNo.Add(2);
            lstEvenNo.Add(4);
            lstEvenNo.Add(6);
            lstEvenNo.Add(8);
            lstEvenNo.Add(10);
            Thread.Sleep(1000);
            Console.WriteLine("Thread {0} Completed GetEvenNumber at {1}", System.Threading.Thread.CurrentThread.ManagedThreadId, DateTime.Now);
            return lstEvenNo;
        }

        public List<int> GetOddNumber()
        {
            Console.WriteLine("Thread {0} started GetOddNumber at {1}", System.Threading.Thread.CurrentThread.ManagedThreadId, DateTime.Now);
            List<int> lstOddNo = new List<int>();
            lstOddNo.Add(1);
            lstOddNo.Add(3);
            lstOddNo.Add(5);
            lstOddNo.Add(7);
            lstOddNo.Add(9);
            Thread.Sleep(1000);
            Console.WriteLine("Thread {0} Completed GetOddNumber at {1}", System.Threading.Thread.CurrentThread.ManagedThreadId, DateTime.Now);
            return lstOddNo;
        }
}

Config File :

<services>
      <service name="HelloWCFService.Service1" behaviorConfiguration="mexBehaviour">
        <endpoint address="HelloWCFService" binding="basicHttpBinding" contract="HelloWCFService.IService1"></endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"></endpoint>
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:49416/"/>
            <!--<add baseAddress="net.tcp://localhost:9210/"/>-->
          </baseAddresses>
        </host>
      </service>
    </services>

Client Code : Client code is implemented using Windows Form Application.
In following code Background worker is used to send asynchronous request. 

public partial class Concurrency : Form
    {
        SimpleService.Service1Client simpleServiceClient;
        public Concurrency()
        {
            InitializeComponent();
            simpleServiceClient = new SimpleService.Service1Client();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            backgroundWorker1.RunWorkerAsync();  
        }

        private void button2_Click(object sender, EventArgs e)
        {
            backgroundWorker2.RunWorkerAsync();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            lstEvenNo.DataSource = null;
            lstOddNo.DataSource = null;
        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            e.Result = simpleServiceClient.GetEvenNumber();
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            lstEvenNo.DataSource = (int[])e.Result;
        }

        private void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e)
        {
            e.Result = simpleServiceClient.GetOddNumber();
        }

        private void backgroundWorker2_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            lstOddNo.DataSource = (int[])e.Result;
        }
    }

Client/Service Output :
In the below image, when we click EvenNumber and OddNumber button at a time.
See the red highlighted service log, both thread start executing code without waiting to complete other thread.


























For detailed description about other concurrency mode please visit following posts.
Single-concurrency-mode-in-wcf
Multiple-concurrency-mode-in-wcf
Reentrant-concurrency-mode-in-wcf

Thanks :-)

No comments:

Post a Comment