In a lot of WCF examples you’ll see that the proxy is called in a using statement, this is actually not the best or safest way to call your proxy.
When you write
using (ServiceProxy proxy = new ServiceProxy())
{
proxy.SomeAction();
}
It will be translated to something like this:
ServiceProxy proxy = new ServiceProxy();
try
{
proxy.SomeAction();
}
finally
{
if (proxy != null)
((IDisposable)proxy).Dispose();
}
The problem is that proxy.Dispose() will throw an exception when the proxy is in a faulted state and could mask any exceptions thrown in the try block. This is not a desirable effect, in the finally block we just want to cleanup the proxy even if it’s in a faulted state. The solution I propose will let you use your proxy in safe and clean way.
WcfProxy.Using<ServiceProxy>(proxy =>
{
proxy.SomeAction();
});
or if you want to create the proxy object yourself:
WcfProxy.Using<ServiceProxy>(new ServiceProxy(), proxy =>
{
proxy.SomeAction();
});
You only need to use generics and the Action<> delegate.
public static void Using<TProxy>(TProxy proxy, Action<TProxy> action)
where TProxy : ICommunicationObject
{
try
{
action(proxy);
}
catch (Exception)
{
proxy.Abort();
throw;
}
try
{
proxy.Close();
}
catch (Exception)
{
proxy.Abort();
}
}
In the attached .cs file you will find the complete implementation and an overloaded method that will create the proxy instance for you. The .snippet file will save you even more work.
Update:
If the service returns data you have three ways of getting/using that data. The first way is to do everything in the delegate/lambda you pass to the Using() method.
WcfProxy.Using<ServiceProxy>(proxy =>
{
List<Contact> contacts = proxy.GetContacts();
// do more work here
});
The second way is to use "external" variables in the lambda:
List<Contact> contacts = null;
WcfProxy.Using<ServiceProxy>(proxy =>
{
contacts = proxy.GetContacts();
});
// do more work here
The third way is to create an additional Using() method:
public static TReturn Using<TProxy, TReturn>(TProxy proxy, Func<TProxy, TReturn> function)
where TProxy : ICommunicationObject
{
TReturn result = default(TReturn);
try
{
result = function(proxy);
}
// ...
return result;
}
And use it like this:
List<Contact> contacts = WcfProxy.Using<ServiceProxy, List<Contact>>(new ServiceProxy(), proxy =>
{
return proxy.GetContacts();
});
Other WCF articles:
- MaxItemsInObjectGraph and keeping references when serializing in WCF
- Tracing WCF messages
- WCF Routing









