Friday, June 12, 2009

How to reconnect to WCF service after exception occurred

There can be several reasons to raise exception when calling a WCF service. I am not going to discuss why the exception can be occurred. I will, however, discuss here how to reconnect to WCF service after exception.

If any exception occurs while calling WCF service, the proxy of the WCF service goes to invalid state. Invalid means you cannot use that proxy any more. You have to recreate the proxy before calling any operation of the service.

I will use ChannelFactory here in order to create the proxy of the WCF service. Let the service contact is IService. The following code snippet shows how a proxy would be created using ChannelFactory:

private static ChannelFactory _Factory;
private static IService _Proxy;
public static Timer _reconnectTimer;
public static bool CreateProxy()
{
try
{

//get the factory instance
_Factory = new ChannelFactory("ServiceEndpoint");

_Proxy = _jerichoFactory.CreateChannel();
_Proxy.IsServiceLive();
//add the faulted event
((ICommunicationObject)_Proxy).Faulted += new EventHandler(Proxy_Faulted);

if (_reconnectTimer != null)
{
_reconnectTimer.Stop();
}
}
catch (Exception)
{
return false;
}

return true;
}

In the above code, I have subscribed the Faulted event of the proxy. Make sure you have cast the proxy into ICommunicationObject. Faulted event is fired whenever any exception occurres during the service call. Notice, I have called IsServiceLive() method after creating the channel. IsServiceLive() method simply returns true to make sure that the proxy can connect to the service. The following code snippet is the implementation of Faulted event.

static void Proxy_Faulted(object sender, EventArgs e)
{
IChannel channel = sender as IChannel;
if (channel != null)
{
channel.Abort();
channel.Close();
}
//Disable the keep alive timer now that the channel is faulted
//The proxy channel should no longer be used
AbortProxy();
//fire the OnProxyFaulted event
if (OnProxyFaulted != null)
{
OnProxyFaulted(null, null);
}
if (_reconnectTimer == null)
{
_reconnectTimer = new Timer(2000 * 60);
_reconnectTimer.Elapsed += new ElapsedEventHandler(ReconnectTimer_Elapsed);
}

//Enable the try again timer and attempt to reconnect
_reconnectTimer.Start();
}

static public void AbortProxy()
{
if (_Factory != null)
{
_Factory.Abort();
_Factory.Close();
_Factory = null;
}
}

In the implementation of the Faulted event, I have canceled and aborted the channel of the proxy. After that, I have created a time which will be fired in every two seconds. Let’s see the implementation of the timer.

static void ReconnectTimer_Elapsed(object sender, ElapsedEventArgs e)
{
if (CreateProxy())
{
_reconnectTimer.Stop();
}
}

This is very straightforward implementation of the timer. If it can create the proxy and connect to the service, it will stop the timer. This is how you can reconnect to the WCF service after exception.

I could have created the proxy in the Faulted event. But it is better to use a timer to poll the service after a certain time.

Happy programming!

4 comments:

Unknown said...

Nice, this is what I was looking for.
Just one question: what is "_jerichoFactory"? I didn't see it declared or explained anywhere

Atiquzzaman Setu said...

Thank you for reading my blog.

"_jerichoFactory" is typo here. It should be "_Factory" instead of "_jerichoFactory".

Thichca2 said...

Hi,
In .net remoting I do not have to re-create my object again if my network is disconnected.
Why would it need in WCF?
It is really inconvenient if it is just a network glitch and your app just need to try again

Owi said...

shouldn't we stop reconnect timer after proxy opened event fire??