locked
Is there a best practice to catching communications/timeout exceptions? RRS feed

  • Question

  • Hi,
     i have a client that makes server calls. the client's proxy holds 20 methods published at the server.
    we are using VS2008 wcf tcp binding.
    sometimes, the server's socket goes down and comes right back resulting in the following exception : 
    The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '00:11:00 '

    i want to be able to call the method again whenever i get this kind of error in order to renew the proxy, but, i don't want to catch the exception for 20 methods but to catch them in one place (one method) and execute the failed method again.

    is there a way to do this?
    Tuesday, December 9, 2008 3:07 PM

Answers

  • No need to use AOP which I think it's heavy-weight for this type of scenario, lamda expression could help here:

    public static class WcfHelper
    {
        public static void Invoke<T>(this T serviceChannel, Action<T> action) where T : ICommunicationObject
        {
            try
            {
                action(serviceChannel);
            }
            catch (CommunicationException ex)
            {
                //Log Exception message here.
                Console.WriteLine(ex.Message);
                if (serviceChannel != null)
                {
                    if (serviceChannel.State != CommunicationState.Closed || serviceChannel.State != CommunicationState.Faulted)
                    {
                        serviceChannel.Close();
                    }
                    else if (serviceChannel.State == CommunicationState.Faulted)
                    {
                        serviceChannel.Abort();
                    }
                }
            }
        }
    }

    And you can call the services as follows:

    var client = new DemoServiceClient();
    client.Invoke<DemoServiceClient>(proxy => { messages.Add(proxy.GetData(3)); });

    And in the similar vein, you could try wrapping the re-try logic inside the WcfHelper extension methods.

    Thanks

    Another Paradigm Shift
    http://shevaspace.blogspot.com
    • Marked as answer by gash Sunday, December 14, 2008 2:41 PM
    Friday, December 12, 2008 6:16 AM

All replies

  • Hello,

    But anyway, such exception can fail the channel, so you would need to re-instantiate the proxy. You should treat all exceptions (that are not WCF failures) as technical exceptions that fail channel of the proxy.

    Therefore I would create a wrapper class (kind of service agent) that would internally use proxy class. If you want to avoid code duplication in all 20 methods of new wrapper class, use AOP (aspect oriented programming) frameworks like enterprise library policy injection or spring.net.

    Vitaliy Liptchinsky http://dotnetframeworkplanet.blogspot.com/
    Tuesday, December 9, 2008 3:58 PM
  • thanks for the reply.
    doesn't WCF have any kind of built in solution for this pretty common issue?
    is the only solution aspect programming solution?
    Guy.
    Tuesday, December 9, 2008 4:24 PM
  • No need to use AOP which I think it's heavy-weight for this type of scenario, lamda expression could help here:

    public static class WcfHelper
    {
        public static void Invoke<T>(this T serviceChannel, Action<T> action) where T : ICommunicationObject
        {
            try
            {
                action(serviceChannel);
            }
            catch (CommunicationException ex)
            {
                //Log Exception message here.
                Console.WriteLine(ex.Message);
                if (serviceChannel != null)
                {
                    if (serviceChannel.State != CommunicationState.Closed || serviceChannel.State != CommunicationState.Faulted)
                    {
                        serviceChannel.Close();
                    }
                    else if (serviceChannel.State == CommunicationState.Faulted)
                    {
                        serviceChannel.Abort();
                    }
                }
            }
        }
    }

    And you can call the services as follows:

    var client = new DemoServiceClient();
    client.Invoke<DemoServiceClient>(proxy => { messages.Add(proxy.GetData(3)); });

    And in the similar vein, you could try wrapping the re-try logic inside the WcfHelper extension methods.

    Thanks

    Another Paradigm Shift
    http://shevaspace.blogspot.com
    • Marked as answer by gash Sunday, December 14, 2008 2:41 PM
    Friday, December 12, 2008 6:16 AM
  • The best practice in such scenario is that from your client side you need to cath exception based on TimeOut  and Communication an other service excpetion which could cuase your chanel to fails, then was is recomanded then is to recreate the proxy within the cacth if needed as follow :

    Try {

            Your proxy call here...
          }

    catch (CommunicationException ex)
    {
       myProxy.Abort ( this is important to aborsd the chanel becasue it is definitly dead
       Then recreate the proxy client here if needed
     }
    ......

    catch (Timeout ex)
    {
       myProxy.Abort ( this is important to aborsd the chanel becasue it is definitly dead
       Then recreate the proxy client here if needed
     }

    ...

    Hope it helps
    serge

    Your experience is build from the one of others
    Friday, December 12, 2008 11:23 AM