WCF/С# Не удалось поймать EndpointNotFoundException
Я создал службу WCF и клиент, и все это работает до тех пор, пока не дойдет до ловушек ошибок. В частности, я пытаюсь поймать EndpointNotFoundException
, когда сервер по какой-то причине не существует. Я пробовал простой блок try/catch, чтобы поймать конкретную ошибку и исключение связи, из которого оно происходит, и я попытался поймать только Exception. Никому из них не удается поймать исключение, однако я получаю
Первое случайное исключение типа 'System.ServiceModel.EndpointNotFoundException' произошел в System.ServiceModel.dll
в окне вывода, когда клиент пытается открыть службу. Любые идеи относительно того, что я делаю неправильно?
Ответы
Ответ 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();
}
Ответ 3
Это может быть проблема с сообщением для отладчика, а не исключение. этот пост дает некоторые советы по его разрешению, если это так... Почему исключение .NET не попало в блок try/catch?
Ответ 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");
}