Восстановление после исключения CommunicationObjectFaaledException в WCF

У меня есть клиентское приложение, которое каждые 10 секунд пытается отправить сообщение через веб-службу WCF. Это клиентское приложение будет находиться на компьютере на борту корабля, который, как мы знаем, будет иметь нестабильное подключение к Интернету. Я хотел бы, чтобы приложение пыталось отправлять данные через службу, а если не может, ставило сообщения в очередь до тех пор, пока оно не сможет отправить их через службу.

Чтобы протестировать эту настройку, я запускаю клиентское приложение и веб-службу (обе на моем локальном компьютере), и все работает нормально. Я пытаюсь смоделировать плохое интернет-соединение, отключив веб-службу и перезапустив ее. Как только я убиваю службу, я начинаю получать исключения CommunicationObjectFaaledExceptions, чего и следовало ожидать. Но после перезапуска службы эти исключения продолжают появляться.

Я почти уверен, что чего-то не понимаю в парадигме веб-сервисов, но не знаю, что это такое. Может ли кто-нибудь посоветовать, возможна ли такая установка, и если да, то как решить эту проблему (т.е. восстановить канал связи с веб-службой)?

Спасибо!

Klay


person Klay    schedule 06.08.2009    source источник


Ответы (1)


Прокси-серверы клиентской службы нельзя использовать повторно после того, как они вышли из строя. Вы должны избавиться от старого и создать новый.

Вы также должны убедиться, что вы правильно закрыли прокси-сервер клиентской службы. Прокси-сервер службы WCF может вызвать исключение при закрытии, и если это произойдет, соединение не будет закрыто, поэтому вы должны прервать его. Используйте шаблон "попробуйте {Close} / catch {Abort}". Также имейте в виду, что метод dispose вызывает close (и, следовательно, может вызывать исключение из dispose), поэтому вы не можете просто использовать using like с обычными одноразовыми классами.

Например:

try
{
    if (yourServiceProxy != null)
    {
        if (yourServiceProxy.State != CommunicationState.Faulted)
        {
            yourServiceProxy.Close();
        }
        else
        {
            yourServiceProxy.Abort();
        }
    }
}
catch (CommunicationException)
{
    // Communication exceptions are normal when
    // closing the connection.
    yourServiceProxy.Abort();
}
catch (TimeoutException)
{
    // Timeout exceptions are normal when closing
    // the connection.
    yourServiceProxy.Abort();
}
catch (Exception)
{
    // Any other exception and you should 
    // abort the connection and rethrow to 
    // allow the exception to bubble upwards.
    yourServiceProxy.Abort();
    throw;
}
finally
{
    // This is just to stop you from trying to 
    // close it again (with the null check at the start).
    // This may not be necessary depending on
    // your architecture.
    yourServiceProxy = null;
}

Об этом есть статья в блоге < / а>

person Simon P Stevens    schedule 06.08.2009
comment
+10, если бы я мог - вау, это поведение полностью скрыто, никогда бы не понял, что происходит, если бы я не наткнулся на этот ответ. - person David Hall; 04.10.2009
comment
Браво! Я реализовал эту версию как метод расширения: TryDispose в прокси-классе для использования другими. - person Moby's Stunt Double; 23.11.2013
comment
@ Moby's Stunt Double - можете ли вы поделиться своим кодом? - person RichardHowells; 22.11.2014
comment
Codepaste-Link: Страница не найдена. - person BluE; 02.10.2018