Я пытаюсь расширить этот ответ на 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();
}
}
}