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.
- 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.
- 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 1.
ConcurrencyMode Single
is defined as follows:[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single)]
public class VisitorCount : IVisitorCount
{
}
Figure 2
Here is how we would define ConcurrencyMode Multiple
.[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
public class VisitorCount : IVisitorCount
{
}
Figure 3
Decorating service class with ConcurrencyMode Reentrant
.[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant)]
public class VisitorCount : IVisitorCount
{
}
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.
- 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.
- 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 4.
Here is how we would define InstanceContext Mode Percall
.[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single,
InstanceContextMode = InstanceContextMode.PerCall)]
public class VisitorCount : IVisitorCount
{
}
Figure 5.
Here is how we would define InstanceContextMode PerSession
.[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single,InstanceContextMode = InstanceContextMode.PerSession)]
public class VisitorCount : IVisitorCount
{
}
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
<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 withServiceContract 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();
}
}
No comments:
Post a Comment