Introduction
It has been a while since I was thinking of sharing some WCF service optimization techniques which we can easily implement as part of Service framework and service client side. This article talks about the following important points:
There is nothing new in this article other than using C# list objects to cache services and objects from service. This includes an XML file which is easy to map objects and its types to create objects at run time using factory pattern.
The UML high level design picture shows everything explained in this article. I am sure we can do some more optimization in this project, but for the time being I just want to present a few areas where we can improve performance of Service Communication.
What is the Main Time Consuming Process in WCF Service Call?
One of the main time consuming processes in any service call or any call to the outside application boundary is initiating and opening the connection across the channel. That is where we need connection pooling. In WCF service call we can easily achieve with caching service channels at client side. This article gives you with channel caching and object caching to improve speed.
The following picture will clarify everything:
Prerequisites
You will need VS 2010 to open the Solution, but I am sure the same code will work in VS 2008 as well if you create another VS 2008 solution and add these files.
Solution Overview
If you look at the following picture, you can easily understand the different layers and files included. Probably you can download the attached code and dig into each file to get more about implementation.
Using the Code
The code below does Client side service caching. It is also tested with multi threading since multiple threads will be accessing cache collection object asynchronously.
public static I CreateInstance<I>() where I : class
{
string endPointConfig = typeof(I).Name.ToString();
lock (_channels.SyncRoot)
{
if (_channels.ContainsKey(endPointConfig) == false)
{
_channels.Add(endPointConfig, OpenChannel<I>());
}
else if (((((IClientChannel)_channels[endPointConfig]).State ==
CommunicationState.Faulted)) ||
(((IClientChannel)_channels[endPointConfig]).State ==
CommunicationState.Closed) ||
(((IClientChannel)_channels[endPointConfig]).State ==
CommunicationState.Closing))
{
((IClientChannel)_channels[endPointConfig]).Abort();
((IClientChannel)_channels[endPointConfig]).Close();
_channels.Remove(endPointConfig);
_channels.Add(endPointConfig, OpenChannel<I>());
}
return _channels[endPointConfig] as I;
}
}
This part of code is to create channel and open the channel.
private static I OpenChannel<I>() where I : class
{
string endPointConfig = typeof(I).Name.ToString();
ChannelFactory<I> factory = new ChannelFactory<I>(endPointConfig);
factory.Open();
I channel = factory.CreateChannel();
((IClientChannel)channel).Faulted += new EventHandler(ServiceFactory_Faulted);
return channel;
}
This part of code gets executed when service is faulty and the same time we need to remove from Cache collection.
static void ServiceFactory_Faulted(object sender, EventArgs e)
{
((ICommunicationObject)sender).Abort();
((ICommunicationObject)sender).Close();
Type typ = ((ICommunicationObject)sender).GetType();
lock (_channels.SyncRoot)
{
((ICommunicationObject)sender).Faulted -= new EventHandler(ServiceFactory_Faulted);
_channels.Remove(typ.Name);
}
}
This code part does object pooling and is used in Service host when a service invokes a business object.
ObjectFactory.cs
public static I CreateInstance<I>() where I : class
{
lock (_pooledObjects.SyncRoot)
{
if (_pooledObjects.ContainsKey(typeof(I)) == false)
{
_pooledObjects.Add(typeof(I), GetInstance<I>());
}
return _pooledObjects[typeof(I)] as I;
}
}
That's All About It - Quite Simple
I hope this approach is very simple and good to implement. Please have a look and if you like this article, please leave a vote and a comment. Thanks. Any comments and questions will be appreciated.
Points of Interest
I am always concentrating to deliver high performance applications with easy customized approach. I spent some time to tune WCF service with the help of many memory profilers like ants profiler.