Introduction
In this small tip, we will discuss about the various concurrency modes available in a WCF service. We will see what are the impact of using these concurrency modes and how they work in unison with the InstanceContextModes
. We will also look into WCF throttling and how we can control the number of concurrent calls and other WCF configuration parameters.
Background
We have seen how the WCF service provides various instancing modes(refer this: A Beginner's Tutorial for Understanding WCF Instance Management [^]). Instance modes is only one aspect related to the WCF services. Whenever a client calls a WCF service function this instance of the WCF service class is created on a thread that is taken from a thread pool. Once the instance is used and no longer needed, the thread will be returned to the thread pool so that it can be reclaimed for further requests.
WCF Concurrency modes gives us the possibility of taking control over these thread creation process so that a WCF service creator can take better, desirable and perhaps more control on the WCF service behavior.
Using the code
Let us now look at the various possible concurrency modes:
Single
Multiple
Reentrant
Single
In Single
mode, there will be only one thread that can use the instance of WCF service class. If any thread has already created an instance of the class then further requesting threads can create the instance but they will have to wait for first thread to finish using its instance and then it will get a change to execute the operation on its instance.
This is the default mode and this mode is safest from the concurrency perspective as the developer will not have to take care of concurrency issues in the code.
This mode can be visualized as that before calling each function the thread acquires a lock and after the call is complete the thread releases the lock so that other thread can proceed with the execution.
Now since this mode allows only one thread to process the instance at a time, this behavior will be same irrespective of the instance mode. i.e. in InstanceContextMode.Single
, InstanceContextMode.PerSession
and InstanceContextMode.PerCall
only a single thread will be allowed to access the instance of the WCF service class.
Multiple
In Multiple
mode, each thread will have its own instance of the WCF service object and they all will be executing at the same time. Now this is the most complicated mode because all the concurrency issues must be handled by the service.
Now let us see what is the behavior with various InstanceContext
Modes:
InstanceContextMode.Single
: In this mode, only one instance will serve all the client requests and since the ConcurrencyMode
is also set to Multiple
, multiple threads will be created for all the clients. InstanceContextMode.PerSession
: Now in this mode, single instance of the service will be created for each client and since the ConcurrencyMode
is set to Multiple
, mulitple threads can be created for each client request. InstanceContextMode.PerCall
: Now in this mode a new instance is created for every call so ConcurrencyMode
set as Multiple
will not have much impact on behavior and every call will be processed in a single thread.
Reentrant
The Reentrant
mode is similar to the Single mode in a way that each thread can create its own instance but to execute the instance, they will have to wait for any other thread to finish using the instance. The main difference in this mode is that if the first thread's instance either calls some other service or process the client callback, the second thread's instance will be given a chance to execute.
Now since this is similar to Single mode and allows only one thread to process the instance at a time, this behavior will be same irrespective of the instance mode. i.e. in InstanceContextMode.Single
, InstanceContextMode.PerSession
and InstanceContextMode.PerCall
only a single thread will be allowed to access the instance of the WCF service class but as soon as the instance calls any other service or go for processing client callbacks, the other thread will get a chance to execute its own instance of WCF service class.
Note: We have only talked about the ConcurrencyModes
from a theoretical perspective. In most cases the ConcurrencyMode.Single
is used. Also, it in a stateless scenario, where the default instance mode is PerCall
, making a change in the ConsurrencyMode
will not have any effect/impact and thus there will rarely be a case when we would want to change the default behavior of the concurrency mode (and even if we change it, it will be futile).
A note on Throttling
Setting the InstanceContextMode
and ConcurrencyMode
will take care of the service behavior. But how should or could be address the issues related to number of clients accessing the service, the number of threads that can access the service or for instance the number of sessions that are allowed to be created for this service.
If we can take control on such issues then we can be sure that our service will behave in a consistent fashion even if it is being over consumed in terms of requests, sessions and/or calls.
WCF throttling gives us the possibility f specifying and configuring these limits to protect the service from over consumption. We can use the ServiceThrottle
class to set these limits via code(imperatively) or we can set these in the serviceBehavior
section of the service's web.config file(declaratively). The major properties that can be set are:
MaxConcurrentSessions
MaxConcurrentInstances
MaxConcurrentCalls
Point of interest
This was a small tip talking about the theoretical aspects of WCF concurrency and throttling. I have not provided any sample code for this tip because I myself never had the chance to configure the ConcurrencyMode
because I am mostly working with stateless services. But knowing about these modes sure is important because we should be aware of these things for when we might need them.
History
- 02 April 2013: First version.