Исключение в операторе "using", когда WCF не закрывает соединения должным образом. Как закрыть неисправные клиентские соединения WCF или соединения с исключениями? - PullRequest
5 голосов
/ 19 февраля 2011

В StackOverflow есть несколько вопросов, касающихся закрытия соединений WCF, однако ответы с самым высоким рейтингом относятся к этому блогу:

http://marcgravell.blogspot.com/2008/11/dontdontuse-using.html

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

Проблема в том, что клиент "зависает", пока сервер не завершит обработку. Я предполагаю, что все очищается после исключения.

Что касается TimeOutException, то, по-видимому, логика retry() клиента будет продолжать повторно отправлять запрос на сервер снова и снова, где я вижу, как отладчик на стороне сервера выстраивает в очередь запросы и затем одновременно выполнять каждый запрос в очереди . Мой код не ожидал, что WCF будет действовать таким образом, и это может быть причиной проблем с повреждением данных, которые я вижу.

Что-то не совсем суммируется с этим решением.

Что такое всеобъемлющий современный способ иметь дело с ошибками и исключениями в прокси WCF?

Ответы [ 2 ]

7 голосов
/ 19 февраля 2011

Обновление

По общему признанию, это немного мирского кода для записи. В настоящее время я предпочитаю этот связанный ответ и не вижу в этом коде "хаков", которые могут вызвать проблемы в будущем.


Это рекомендуемый Microsoft способ обработки вызовов клиента WCF:

Подробнее см .: Ожидаемые исключения

try
{
    ...
    double result = client.Add(value1, value2);
    ...
    client.Close();
}
catch (TimeoutException exception)
{
    Console.WriteLine("Got {0}", exception.GetType());
    client.Abort();
}
catch (CommunicationException exception)
{
    Console.WriteLine("Got {0}", exception.GetType());
    client.Abort();
}

Дополнительная информация Похоже, что так много людей задают этот вопрос на WCF, что Microsoft даже создала специальный образец, чтобы продемонстрировать, как обрабатывать исключения:

C: \ WF_WCF_Samples \ WCF \ Basic \ Client \ ExpectedExceptions \ CS \ клиент

Скачать образец: C # или VB

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

Необязательные дополнительные ошибки при отлове

Многие исключения происходят из CommunicationException, и я не думаю, что большинство из этих исключений следует повторить. Я пролистал каждое исключение в MSDN и нашел короткий список повторяющихся исключений (в дополнение к TimeOutException выше). Дайте мне знать, если я пропустил исключение, которое следует повторить.

Exception   mostRecentEx = null;
for(int i=0; i<5; i++)  // Attempt a maximum of 5 times 
{
    try
    {
       ...
       double result = client.Add(value1, value2);
       ...
       client.Close();
    }

    // The following is typically thrown on the client when a channel is terminated due to the server closing the connection.
    catch (ChannelTerminatedException cte)
    {

      mostRecentEx = cte;
      secureSecretService.Abort();
        //  delay (backoff) and retry 
        Thread.Sleep(1000 * (i + 1)); 
    }

    // The following is thrown when a remote endpoint could not be found or reached.  The endpoint may not be found or 
    // reachable because the remote endpoint is down, the remote endpoint is unreachable, or because the remote network is unreachable.
    catch (EndpointNotFoundException enfe)
    {

      mostRecentEx = enfe;
     secureSecretService.Abort();
        //  delay (backoff) and retry 
        Thread.Sleep(1000 * (i + 1)); 
    }

    // The following exception that is thrown when a server is too busy to accept a message.
    catch (ServerTooBusyException stbe)
    {
      mostRecentEx = stbe;
        secureSecretService.Abort();

        //  delay (backoff) and retry 
        Thread.Sleep(1000 * (i + 1)); 
    }

    catch(Exception ex)
    { 
         throw ex;  // rethrow any other exception not defined here
    }
}
if (mostRecentEx != null) 
{
    throw new Exception("WCF call failed after 5 retries.", mostRecentEx );
}
3 голосов
/ 19 февраля 2011

Закрытие и удаление службы WCF

Как указывается в этом сообщении, вы закрывались, когда не было исключений, и отменяли при возникновении ошибок.Dispose и, следовательно, Using не следует использовать с WCF.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...