Introduction
This article will explain how we can achieve through puts, reliability and performance using various WCF Service behavior techniques.
Most application differs widely in their scalability and performance strategies. WCF service behaviors provide various possible ways
to configure key run time behaviors. We will go through various service behavior elements one by one.
Concurrency
By default WCF service handles only single request at a time and all other service request threads are queued and processed one by one.
Concurrency element allows clients to send multiple requests at the same time, but service implementation should be break free of scenarios like dead locks.
There are three types of Concurrency modes.
- Single(Default): Concurrency mode single will allows only one at a time to the service instance. And all other pending requests will be maintained in queue and processed one by one. Whenever a new request
comes dispatcher gets a lock before entering in to the code. Refer Figure 1.
Figure 1.
ConcurrencyMode Single
is defined as follows:
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single)]
public class VisitorCount : IVisitorCount
{
}
- Multiple: This will allow parallel requests, and that are processed at the same time by spawning separate thread for each
and every request. Refer Figure 2.
Figure 2
Here is how we would define ConcurrencyMode Multiple
.
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
public class VisitorCount : IVisitorCount
{
}
- Re-entrant: Whenever a client calls WCF service a thread lock will be assigned to this client call. Let us consider a scenario where Service 1 makes an external call to Service 2. Thread lock won’t be released until entire service call is completed. So all other client requests are in waiting state. Re-entrant allows the client to release the lock before making call to the external service (Service 2) and this will allow other client to use the Service 1 facilities until
Service 2 process is completed. Refer Figure 3.
Figure 3
Decorating service class with ConcurrencyMode Reentrant
.
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant)]
public class VisitorCount : IVisitorCount
{
}
Concurrency mode can increase the amount of passing through the service methods and hence overall service performance increases.
Instance Context Mode
WCF Instancing decides how objects are created and refers to the life time of the service object. Whenever clients make request runtime will create
service objects to provide the response. Through instancing we ca control how long this service instance wants to be retained.
For that we are using the three instancing modes.
- Per Call: In this scenario, all the calls to the service become stateless. And for every thread request a new
service instance will be created. This will work with all the service bindings. Refer Figure 4.
Figure 4.
Here is how we would define InstanceContext Mode Percall
.
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single,
InstanceContextMode = InstanceContextMode.PerCall)]
public class VisitorCount : IVisitorCount
{
}
- Per Session: The life time of service object is independent of the life time of Client channels, so this will create a new service
object whenever a new communication session is established and disposed after that. Each client channel gets a dedicated service instance and the subsequent
calls in the same session are handled by the same Service object. This is the default value for Instancing Context. And this will work with all
bindings except basicHttpBindings. Refer Figure 5.
Figure 5.
Here is how we would define InstanceContextMode PerSession
.
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single,InstanceContextMode = InstanceContextMode.PerSession)]
public class VisitorCount : IVisitorCount
{
}
- Single: This will help us to share the data globally. We can create only one instance and the same instance will be reused on the subsequent calls.
Same like Per Session this will work with all bindings except basicHttpBinding. Single ton instance will not be disposed until service host is down. Refer Figure 6.
Figure 6
Here is how we would define InstanceContext mode Single
.
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single,InstanceContextMode = InstanceContextMode.Single)]
public class VisitorCount : IVisitorCount
{
}
Service Throttling
WCF allows you to throttle load on a particular service type.
This includes
- Maximum number of Concurrent sessions
- Maximum number of Concurrent calls
- Maximum number of Concurrent instances
Whenever these values exceeded, the callers will be added to the queue and processed FIFO order. We can configure throttling behavior in application configuration file as follows.
<serviceBehaviors>
<behavior name="visitorCountServiceBehavior">
<serviceThrottling maxConcurrentCalls="5" maxConcurrentInstances="10" maxConcurrentSessions="10">
</serviceThrottling>
</behavior>
</serviceBehaviors>
Using the code
Let us create a sample application to demonstrate different service behaviors. First create an interface and decorate it with ServiceContract and OperationalContract
attributes to specify that these operations
of this interface can be used by the client applications.
[ServiceContract]
public interface IVisitorCount
{
[OperationContract]
int GetVisitorCount();
}
Now we have to create a service class to implement above interface method. And we have to decorate service class with different service behaviors, following code explains Concurrency
Mode Single and Instance context mode single.
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single,InstanceContextMode = InstanceContextMode.Single)]
public class VisitorCount : IVisitorCount
{
int _visitorCount = 0;
public VisitorCount()
{
Console.WriteLine("New Service Instance Created");
}
public int GetVisitorCount()
{
_visitorCount++;
return _visitorCount;
}
}
Now let us see how we can make this service available to client applications, Configuration file App.Config contents are given below.
<configuration>
<system.web>
<compilation debug="true">
</compilation></system.web>
<system.servicemodel>
<services>
<service name="InstanceContextModeService.VisitorCount">
<endpoint binding="wsHttpBinding" contract="InstanceContextModeService.IVisitorCount">
<identity>
<dns value="localhost">
</dns></identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange">
<host>
<baseAddresses>
<add baseaddress="http://localhost:8732/InstanceContextModeService/VisitorCount/">
</baseAddresses>
</add></host>
</endpoint></service>
</services>
<behaviors>
<servicebehaviors>
<behavior>
<servicemetadata httpgetenabled="True">
<servicedebug includeexceptiondetailinfaults="False">
<servicethrottling maxconcurrentcalls="5" maxconcurrentinstances="10" maxconcurrentsessions="10">
</servicethrottling></servicedebug></servicemetadata><</behavior>
</servicebehaviors>
</behaviors>
</system.servicemodel>
</configuration>
Following service host code will host VisitorCounter
service to the client applications.
class Program
{
private static ServiceHost host = null;
static void Main(string[] args)
{
host = new ServiceHost(typeof(InstanceContextModeService.VisitorCount));
host.Opened += new EventHandler(host_Opened);
host.Closed += new EventHandler(host_Closed);
host.Open();
Console.ReadKey();
host.Close();
Console.ReadKey();
}
static void host_Closed(object sender, EventArgs e)
{
Console.WriteLine("Service Closed");
}
static void host_Opened(object sender, EventArgs e)
{
Console.WriteLine("Service Started");
}
}
We have our service is hosted and defined. Following code explains how clients utilize service and service behaviors.
static class Program
{
static void Main(string[] args)
{
VisitorCountClient client = new VisitorCountClient();
Console.WriteLine("First Call-->" + client.GetVisitorCount());
Console.ReadKey();
Console.WriteLine("Second Call-->" + client.GetVisitorCount());
Console.ReadKey();
Console.WriteLine("Third Call-->" + client.GetVisitorCount());
Console.ReadKey();
Console.WriteLine("Forth Call-->" + client.GetVisitorCount());
Console.ReadKey();
}
}
Download above attached sample application for your reference and go through different service behaviors by changing different behavior attributes as we discussed earlier.
Summary
Whenever we design an enterprise application, it should provide great performance, scalability, through puts and reliability.
WCF can achieve these features with different technologies discussed in this piece of writings.