WCF / C # Невозможно отловить исключение EndpointNotFoundException - PullRequest
18 голосов
/ 17 марта 2010

Я создал службу WCF и клиента, и все это работает, пока не доходит до перехвата ошибок. В частности, я пытаюсь поймать EndpointNotFoundException для случая, когда сервер по какой-то причине не существует. Я пробовал простой блок try / catch, чтобы перехватить конкретную ошибку и исключение связи, из которого она происходит, и я попытался перехватить только Exception. Ни одному из них не удается поймать исключение, однако я получаю

Первое исключение типа 'System.ServiceModel.EndpointNotFoundException' произошло в System.ServiceModel.dll

в окне вывода, когда клиент пытается открыть сервис. Есть идеи, что я делаю не так?

Ответы [ 5 ]

4 голосов
/ 20 апреля 2010

Я смог повторить вашу проблему и заинтересовался (так как мне нужно было то же самое). Я даже исследовал способ обработки \ перехвата исключений первого шанса, но, к сожалению, это невозможно (для управляемого кода) для .net framework 3.5 и ниже.

В моем случае я всегда получаю System.ServiceModel.CommunicationObjectFaultedException всякий раз, когда что-то не так в сервисе или когда я получаю доступ к неработающей услуге. Оказывается, причиной является оператор c # using, поскольку за сценой оператор using всегда закрывает экземпляр клиента службы, даже если исключение уже встречалось (это не не прыгайте, чтобы поймать заявление напрямую).

В результате исходное исключение System.ServiceModel.EndpointNotFoundException будет заменено новым исключением System.ServiceModel.CommunicationObjectFaultedException всякий раз, когда using пытается закрыть экземпляр клиента службы.

Решение, которое я принял, состоит в том, чтобы не использовать оператор using, чтобы при каждом обнаружении исключения внутри блока try оно мгновенно выдавало исключение в блоки catch.

Попробуйте закодировать что-то вроде:

DashboardService.DashboardServiceClient svc = new Dashboard_WPF_Test.DashboardService.DashboardServiceClient();
try
{
    svc.GetChart(0);
}
catch (System.ServiceModel.EndpointNotFoundException ex)
{
    //handle endpoint not found exception here
}
catch (Exception ex)
{
    //general exception handler
}
finally
{
    if (!svc.State.Equals(System.ServiceModel.CommunicationState.Faulted) && svc.State.Equals(System.ServiceModel.CommunicationState.Opened))
    svc.Close();
}

Вместо:

try
{
    using (DashboardService.DashboardServiceClient svc = new Dashboard_WPF_Test.DashboardService.DashboardServiceClient())
    {
        svc.GetChart(0);
    }
}
catch (System.ServiceModel.EndpointNotFoundException ex)
{
    //handle endpoint not found exception here (I was never able to catch this type of exception using the using statement block)
}
catch (Exception ex)
{
    //general exception handler
}

И тогда вы сможете поймать правильное исключение.

3 голосов
/ 20 апреля 2010

Взгляните на этот пост для подробностей об этом возможном решении. Код показывает использование сгенерированного прокси, но он действителен и в ChannelFactory, и в других.

Типичный рисунок здесь-драконов

using (WCFServiceClient c = new WCFServiceClient())
{
    try
    {
        c.HelloWorld();
    }
    catch (Exception ex)
    {
        // You don't know it yet but your mellow has just been harshed.

        // If you handle this exception and fall through you will still be cheerfully greeted with 
        // an unhandled CommunicationObjectFaultedException when 'using' tries to .Close() the client.

        // If you throw or re-throw from here you will never see that exception, it is gone forever. 
        // buh bye.
        // All you will get is an unhandled CommunicationObjectFaultedException
    }
} // <-- here is where the CommunicationObjectFaultedException is thrown

Правильный рисунок:

using (WCFServiceClient client = new WCFServiceClient())
{
    try
    {
        client.ThrowException();

    }
    catch (Exception ex)
    {
        // acknowledge the Faulted state and allow transition to Closed
        client.Abort();

        // handle the exception or rethrow, makes no nevermind to me, my
        // yob is done ;-D
    }
} 

Или, как указано в вашем вопросе без утверждения использования,

WCFServiceClient c = new WCFServiceClient();

try
{
    c.HelloWorld();
}
catch
{
    // acknowledge the Faulted state and allow transition to Closed
    c.Abort();

    // handle or throw
    throw;
}
finally
{
    c.Close();
}
1 голос
/ 17 марта 2010

Это может быть проблема с отчетностью для отладчика, а не перехват исключения. в этой статье даются советы по ее устранению, если это так ... Почему исключение .NET не перехватывается блоком try / catch?

0 голосов
/ 18 февраля 2013

Поместите блок try catch в CompletedMethod .

Пример:

...
geocodeService.ReverseGeocodeCompleted += ReverseGeocodeCompleted(se, ev);
geocodeService.ReverseGeocodeAsync(reverseGeocodeRequest);
}

    private void ReverseGeocodeCompleted(object sender, ReverseGeocodeCompletedEventArgs e)
    {
      try
        {
            // something went wrong ...
            var address = e.Result.Results[0].Address;

        }
        catch (Exception)
        { // Catch Exception
            Debug.WriteLine("NO INTERNET CONNECTION");
        }
0 голосов
/ 17 марта 2010

Что такое исключение для первого шанса?

Большинство сообщений об исключениях первого шанса часто не означает, что есть проблема в коде. Для приложений / компоненты, которые обрабатывают исключения изящно, исключение первого шанса сообщения позволяют разработчику знать, что исключительная ситуация была столкнулся и был обработан.

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