Восстановление из объекта CommunicationObjectFaultedException в WCF

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

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

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

Спасибо!

Клэй

Ответы

Ответ 1

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

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

Например:

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;
}

Здесь есть статья в блоге об этом