Support us .Net Basics C# SQL ASP.NET Aarvi MVC Slides C# Programs Subscribe Download

Part 43 - Single concurrency mode in WCF

Suggested Videos
Part 40 - How to retrieve the sessionid in WCF service and in the client application
Part 41 - Single instance context mode in WCF
Part 42 - SessionMode Enumeration in WCF



In this video we will discuss the Single concurrency mode in WCF with examples.

To understand concurrency better, we need to understand
1. Instance Context Modes in WCF - Discussed in Parts 36 to 42 in WCF video series
2. Multithreading concepts - Discussed in Parts 86 to 97 in C# video series



In addition we also need to understand the term throughput. Throughput is the amount of work done in a specified amount of time.

Multiple threads executing the application code simultaneously is called as concurrency. In general with concurrency we get better throughput. However, concurrency issues can occur when multiple threads access the same resource. In WCF, Service Instance is a shared resource. 

The default concurrency mode in WCF is Single. This means only a single thread can access the service instance at any given point in time. While a request is being processed by the service instance, an exclusive lock is acquired and all the other threads will have to wait until the current request completes and the lock is released. Upon relasing the lock, next thread in the queue can access the service instance.

ConcurrencyMode parameter of the ServiceBehavior attribute controls the concurrency setting
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single)]

ConcurrencyMode can be 
Single
Reentrant
Multiple

In this video we will discuss Single concurrency mode with the 3 different instance context modes available in WCF
PerCall - each request is served by a new instance of the service
PerSession - all requests from a single proxy instance are served by the same service instance
Single - all requests are served by the same instance of the service

Create a WCF Service with name = SimpleService. 

ISimpleService.cs:
using System.Collections.Generic;
using System.ServiceModel;

namespace SimpleService
{
    [ServiceContract]
    public interface ISimpleService
    {
        [OperationContract]
        List<int> GetEvenNumbers();

        [OperationContract]
        List<int> GetOddNumbers();
    }
}

SimpleService.cs: Notice that we have set InstanceContextMode to PerCall and ConcurrencyMode to Single.
using System;
using System.Collections.Generic;
using System.ServiceModel;
using System.Threading;

namespace SimpleService
{
    [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single,
        InstanceContextMode = InstanceContextMode.PerSession)]
    public class SimpleService : ISimpleService
    {
        public List<int> GetEvenNumbers()
        {
            Console.WriteLine("Thread {0} started processing GetEvenNumbers at {1}",
                Thread.CurrentThread.ManagedThreadId, DateTime.Now.ToString());
            List<int> listEvenNumbers = new List<int>();
            for (int i = 0; i <= 10; i++)
            {
                Thread.Sleep(200);
                if (i % 2 == 0)
                {
                    listEvenNumbers.Add(i);
                }
            }
            Console.WriteLine("Thread {0} completed processing GetEvenNumbers at {1}",
                Thread.CurrentThread.ManagedThreadId, DateTime.Now.ToString());
            return listEvenNumbers;
        }

        public List<int> GetOddNumbers()
        {
            Console.WriteLine("Thread {0} started processing GetOddNumbers at {1}",
                Thread.CurrentThread.ManagedThreadId, DateTime.Now.ToString());
            List<int> listOddNumbers = new List<int>();
            for (int i = 0; i <= 10; i++)
            {
                Thread.Sleep(200);
                if (i % 2 != 0)
                {
                    listOddNumbers.Add(i);
                }
            }
            Console.WriteLine("Thread {0} completed processing GetOddNumbers at {1}",
                Thread.CurrentThread.ManagedThreadId, DateTime.Now.ToString());
            return listOddNumbers;
        }
    }
}

Host the WCF service using Console Application. Name it Host. Here is the configuration that goes in the App.config file.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="mexBehavior">
          <serviceMetadata httpGetEnabled="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <service behaviorConfiguration="mexBehavior" name="SimpleService.SimpleService">
        <endpoint address="SimpleService"
                  binding="basicHttpBinding"
                  contract="SimpleService.ISimpleService"
                  />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8080" />
            <add baseAddress="net.tcp://localhost:8090" />
          </baseAddresses>
        </host>
      </service>
    </services>
  </system.serviceModel>
</configuration>

Program.cs :
using System;
using System.ServiceModel;

namespace Host
{
    class Program
    {
        public static void Main()
        {
            using (ServiceHost host = new ServiceHost
                (typeof(SimpleService.SimpleService)))
            {
                host.Open();
                Console.WriteLine("Host started @ " + DateTime.Now.ToString());
                Console.ReadLine();
            }
        }
    }
}

Run the WCF Service.

Now let's create a Windows Forms Application as the client for the WCF service. Name it WindowsClient. Add a reference to the WCF Service.

Design the form as shown below.
concurrency in wcf

For Button1 set,
Name = btnGetEvenNumbers
Text = Get Even Numbers

For Button2 set,
Name = btnGetOddNumbers
Text = Get Odd Numbers

For Button3 set,
Name = btnClearResults
Text = Clear Results

Double click on all the button controls to generate their respective click event handler methods.

For listBox1, set 
Name = listBoxEvenNumbers

For listBox2, set 
Name = listBoxOddNumbers

Drag and drop 2 backgroundworker instances from the toolbox on to the form. Please watch this video to learn about backgroundworker class. Generate DoWork and RunWorkerCompleted event handler methods. Copy and paste the following code in Form1.cs
using System;
using System.ComponentModel;
using System.Windows.Forms;

namespace WindowsClient
{
    public partial class Form1 : Form
    {
        SimpleService.SimpleServiceClient client;

        public Form1()
        {
            InitializeComponent();
            client = new SimpleService.SimpleServiceClient();
        }

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

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

        private void btnClearResults_Click
            (object sender, EventArgs e)
        {
            listBoxEvenNumbers.DataSource = null;
            listBoxOddNumbers.DataSource = null;
        }

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

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

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

        private void backgroundWorker2_RunWorkerCompleted
            (object sender, RunWorkerCompletedEventArgs e)
        {
            listBoxOddNumbers.DataSource = e.Result;
        }
    }
}

Test the WCF service using the Windows Client application while changing the binding and Instance Context Mode.

Whether a WCF service handles client requests concurrently or not depends on 3 things
1. Service Instance Context Mode
2. Service Concurrency Mode and
3. Whether if the binding supports session or not
Single concurrency mode in WCF

wcf tutorial

3 comments:

  1. Dear Venkat Sir,
    In the Sample that is provided, On Service Console, i see two threads hitting the service, in my case after exactly implementing the sample, always always only one thread is hitting the service, On Service Console, it is always printing only one thread, could you please tell me what is that i can do in this case?

    ReplyDelete
  2. I dont see sample link on above article? Can you share here ?

    ReplyDelete
  3. The link to the BackgroundWorker Class example in windows forms application, https://www.youtube.com/watch?v=TwlO5XYeeMo

    ReplyDelete

It would be great if you can help share these free resources