Я пытаюсь расширить этот ответ на SO, чтобы повторить попытку WCF-клиента при неудачных сетевых сбоях и обработать другие ситуации, требующие повторения, такие как истечение срока действия аутентификации.
Вопрос:
Каковы исключения WCF, которые необходимо обработать, и каков правильный способ их обработки?
Вот несколько примеров, которые я надеюсь увидеть вместо или в дополнение к proxy.abort():
- Задержка X секунд перед повторной попыткой
- Закройте и заново создайте новый() WCF-клиент. Утилизируйте старый.
- Не пытайтесь повторить и переустановить эту ошибку.
- Повторите N раз, затем нажмите
Поскольку маловероятно, что один человек знает все исключения или способы их решения, делитесь тем, что знаете. Я обобщу ответы и подходы в примере кода ниже.
    // USAGE SAMPLE
    //int newOrderId = 0; // need a value for definite assignment
    //Service<IOrderService>.Use(orderService=>
    //{
    //  newOrderId = orderService.PlaceOrder(request);
    //}
    /// <summary>
    /// A safe WCF Proxy suitable when sessionmode=false
    /// </summary>
    /// <param name="codeBlock"></param>
    public static void Use(UseServiceDelegateVoid<T> codeBlock)
    {
        IClientChannel proxy = (IClientChannel)_channelFactory.CreateChannel();
        bool success = false;
        try
        {
            codeBlock((T)proxy);
            proxy.Close();
            success = true;
        }
        catch (CommunicationObjectAbortedException e)
        {
                // Object should be discarded if this is reached.  
                // Debugging discovered the following exception here:
                // "Connection can not be established because it has been aborted" 
            throw e;
        }
        catch (CommunicationObjectFaultedException e)
        {
            throw e;
        }
        catch (MessageSecurityException e)
        {
            throw e;
        }
        catch (ChannelTerminatedException)
        {
            proxy.Abort(); // Possibly retry?
        }
        catch (ServerTooBusyException)
        {
            proxy.Abort(); // Possibly retry?
        }
        catch (EndpointNotFoundException)
        {
            proxy.Abort(); // Possibly retry?
        }
        catch (FaultException)
        {
            proxy.Abort();
        }
        catch (CommunicationException)
        {
            proxy.Abort();
        }
        catch (TimeoutException)
        {
         // Sample error found during debug: 
         // The message could not be transferred within the allotted timeout of 
         //  00:01:00. There was no space available in the reliable channel 
         //  transfer window. The time allotted to this operation may have been a 
         //  portion of a longer timeout.
            proxy.Abort();
        }
        catch (ObjectDisposedException )
        {
            //todo:  handle this duplex callback exception.  Occurs when client disappears.  
            // Source: https://stackoverflow.com/info/1427926/detecting-client-death-in-wcf-duplex-contracts/1428238#1428238
        }
        finally
        {
            if (!success)
            {
                proxy.Abort();
            }
        }
    }
