Подтвердить что ты не робот

WCF/С# Не удалось поймать EndpointNotFoundException

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

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

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

4b9b3361

Ответ 1

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

В моем случае я всегда получаю System.ServiceModel.CommunicationObjectFaultedException всякий раз, когда что-то не получается в службе или когда я обращаюсь к службе down. Оказывается, что оператор С# 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
}

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

Ответ 2

Взгляните на этот пост, чтобы узнать подробности этого возможного решения. Код показывает использование сгенерированного прокси-сервера, но он действителен и для 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();
}

Ответ 4

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

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

Ответ 5

Поместите блок catch try в 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");
        }