Introduction
Proxy Classes are used to talk to Windows Communication Foundation (WCF) Services.
A communication channel is open to the WCF Service that must be closed after the calls to the service.
The proper way to close the communication channel is very important.
The WCF proxy is usually generated using Visual Studio or the svcutil tool.
The generated proxy inherits from a base class System.ServiceModel.ClientBase
that implements the IDisposable
interface.
The service can be called in a using
block that automatically calls the Dispose()
method.
using (MyService client = new MyService())
{
...
}
Dispose()
calls the proxy close()
method, that sends a message from the client to the service indicating that the connection session is no longer needed.
A problem can arise with this approach if there is an exception when calling the close()
method. This is why the using
approach is not recommended when calling WCF methods.
If the communication channel is in a faulted state Abort()
should be called and not close()
;
The recommended approach is the Try
-Catch
-Abort
pattern.
This is a simple pattern where a try
...catch
block is used to call the service and in the catch
of an exception, the connection is aborted or closed.
The recommendation by Microsoft in MSDN is:
try
{
...
client.Close();
}
catch (CommunicationException e)
{
...
client.Abort();
}
catch (TimeoutException e)
{
...
client.Abort();
}
catch (Exception e)
{
...
client.Abort();
throw;
}
A generic class for creating and initializing WCF proxy clients can be created to implement the pattern and replace the using
block:
public class WCFProxy
{
public static void Using<t>(Action<t> action)
{
ChannelFactory<t> factory = new ChannelFactory<t>("*");
T client = factory.CreateChannel();
try
{
action(client);
((IClientChannel)client).Close();
factory.Close();
}
catch (Exception ex)
{
IClientChannel clientInstance = ((IClientChannel)client);
if (clientInstance.State == System.ServiceModel.CommunicationState.Faulted)
{
clientInstance.Abort();
factory.Abort();
}
else if (clientInstance.State != System.ServiceModel.CommunicationState.Closed)
{
clientInstance.Close();
factory.Close();
}
throw (ex);
}
}
}
To use the class is as simple as:
WCFProxy.Using((delegate(IMyService client)
{
client.DoWork();
});
CodeProject
I am an Experienced Senior Microsoft Consultant responsible for developing and defining architectures for various projects in a Microsoft environment, using a Service-Oriented Architecture (SOA) and web based applications.
I am also a project manager using agile methodologies and SCRUM.
Software Quality Assurance is a mandatory in every project I am responsible.
As someone said:
“Anyone can program, but not everyone is a programmer...”