Exploring instancing, concurrency and throttling in WCF

Take advantage of instancing, concurrency, and throttling to build WCF services that can scale and are high performant

WCF

WCF

When working in WCF you should be aware of the concepts of instancing, throttling, and concurrency to build services that are scalable and can provide better throughput.

Throttling in WCF is used to limit the service throughput so that the resource consumption (memory, processor, disk, network, etc.) in the system is at an acceptable level, i.e., ensure the service doesn't consume resources beyond acceptable limits. The ServiceThrottlingBehavior class can be used to control the performance of WCF services.

Concurrency

In WCF, concurrency issues can arise when two or more threads try to access the same resource at the same time. Note that a WCF service can handle one single request at a time. Concurrency in WCF enables you to control multiple active threads in an InstanceContext at a particular point of time. In essence, it helps you to configure the number of service instances that can serve multiple concurrent requests. The three possible types of concurrency modes include the following:

Single concurrency mode: In this mode each instance context can have a maximum of one thread that can process the request at a particular point of time. When the next request arrives, it has to wait till the first request has been completed. This also incurs the need of synchronization locks. The following code snippet illustrates how single concurrency mode can be used.

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single)]

public class IDGService : IServiceContract

{

     public string GetMessage()

     {

          return "Hello World!";

     }

}

Multiple concurrency mode: In this mode, the service enables multiple threads to access a service operation at the same point of time. In the multiple concurrency mode of operation, each WCF service has multiple threads which in turn can process the incoming requests concurrently.

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]

public class IDGService : IServiceContract

{

    readonly object lockObj = new object();

    public string GetMessage()

    {

        string message = string.Empty;

        lock (lockObj)

        {

             message = "Hello World!";

        }

        return message;

    }

}

Reentrant concurrency mode: In the reentrant mode of operation, although a single thread can access the service object, the thread can still exit the service and then call another service. The following code snippet shows how you can implement this mode.

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant)]

public class IDGService : IServiceContract

{

     public string GetMessage()

     {

          return "Hello World!";

     }

}

The InstanceContextMode property is used to specify when an instance of the service will be created and its durability. Note that both InstanceContextMode and ConcurrencyMode are specified using the ServiceBehaviorAttribute. The three available instance context mode values include: PerCall, PerSession and Single. In the PerCall mode, the service is single threaded and is stateless. The PerSession mode is the default and is used when you would like to maintain state information between calls originated from the same service consumer.  The Single mode is used when your service needs to maintain state information across clients and you would not need to scale out your service in the future.

Throttling

You can leverage throttling to control and optimize the resource usage and also to achieve a way to balance service performance. Throttling in WCF can be configured declaratively as well as programmatically.

You can configure the maxConcurrentCalls, maxConcurrentInstances , maxConcurrentSessions properties declaratively using the <serviceThrottling> tag in the service configuration file as shown in the code snippet below.

<system.serviceModel>

    <services>

      <service behaviorConfiguration="ServiceBehavior"  name="IDGService">

        <endpoint address="" binding="wsHttpBinding" contract="IServiceContract">

          <identity>

            <dns value="localhost"/>

          </identity>

        </endpoint>

        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>

      </service>

    </services>

    <behaviors>

      <serviceBehaviors>

        <behavior name="ServiceBehavior">

          <serviceMetadata httpGetEnabled="true"/>

          <serviceDebug includeExceptionDetailInFaults="true"/>

          <serviceThrottling maxConcurrentCalls="1000"

                                maxConcurrentInstances ="250"

                                maxConcurrentSessions ="500"/>

        </behavior>

      </serviceBehaviors>

    </behaviors>

</system.serviceModel>

The maxConcurrentCalls property is used to limit the total number of calls across all the service instances. The default value is 16 per processor. The maxConcurrentInstances property is used to specify the total number of service instances that can be allocated at a particular point of time. The default value of this property is Int32.MaxValue. The maxConcurrentSessions property is used to specify the total number of concurrent active sessions that is permissible for a service at a given point of time. The default value is 100 per processor.

Now that we know how to configure service throttling in WCF declaratively, let’s explore how we can configure service throttling in WCF programmatically. To configure service throttling in WCF programmatically, you would need to take advantage of the ServiceThrottlingBehavior class. The following code listing shows how you can take advantage of the ServiceThrottlingBehavior class to configure the concurrent calls, session and instance properties.

ServiceHost serviceHost = new ServiceHost(typeof(IDGService));

           ServiceThrottlingBehavior throttleBehavior = serviceHost.Description.Behaviors.Find();

            if (throttleBehavior == null)

            {

                throttleBehavior = new ServiceThrottlingBehavior();

                throttleBehavior.MaxConcurrentCalls = 1000;

                throttleBehavior.MaxConcurrentSessions = 250;

                throttleBehavior.MaxConcurrentInstances = 500;

              serviceHost.Description.Behaviors.Add(throttleBehavior);

            }

In the above code snippet, an instance of ServiceThrottlingBehavior is created and its properties set to the appropriate values. Next, this instance is added to the Behaviors collection of the service host instance.

This article is published as part of the IDG Contributor Network. Want to Join?

From CIO: 8 Free Online Courses to Grow Your Tech Skills
Notice to our Readers
We're now using social media to take your comments and feedback. Learn more about this here.