2010-03-16 31 views
18

He creado un servicio y un cliente WCF y todo funciona hasta que se trata de detectar errores. Específicamente estoy tratando de atrapar el EndpointNotFoundException para cuando el servidor no esté allí por alguna razón. He intentado un simple bloque try/catch para detectar el error específico y la excepción de comunicación de la que proviene, y he intentado detectar solo Exception. Ninguno de ellos tiene éxito en la captura de la excepción, sin embargo yo entiendoWCF/C# No se puede capturar EndpointNotFoundException

Una primera excepción del tipo 'System.ServiceModel.EndpointNotFoundException' ocurrió en System.ServiceModel.dll

en la salida ventana cuando el cliente intenta abrir el servicio. ¿Alguna idea de lo que estoy haciendo mal?

+0

Tal vez usted está tratando de ponerse en el lugar equivocado. ¿Has probado habilitar "Romper cuando se lanza una excepción"? (Depurar -> Excepciones del menú en VS) –

+0

Sí, lo sé, así que sé que lo estoy atrapando en el lugar correcto. – paj777

+0

Cuéntanos y publica el código que está fallando. Tengo un presentimiento, pero no tiene sentido escribir una respuesta sin más información. – Aaronaught

Respuesta

1

Esto puede ser un problema de informe para el depurador, en lugar de no captar realmente la excepción. este post da algunos consejos sobre cómo resolver, si ese es el caso ... Why is .NET exception not caught by try/catch block?

+0

Eché un vistazo rápido a ese hilo pero no parecía haber nada allí para ayudar en este caso. Este no es un error no controlado, el programa no falla, la excepción se maneja solo por mi programa. – paj777

0

What is a First Chance Exception?

primera oportunidad mensajes de excepción más menudo no quieren decir que hay un problema en el código . Para las aplicaciones/ componentes que manejan las excepciones con gracia, la primera oportunidad de excepción mensajes informa al desarrollador que se encontró y se manejó una situación excepcional .

+0

Soy consciente de lo que es una excepción de primera oportunidad. En este caso, sé que la excepción se produce porque el servidor no está allí y me gustaría decirle al usuario del sistema que el servidor no está allí, por lo tanto, me gustaría que mi código maneje la excepción. – paj777

+0

En ese caso, usaría Reflector para rastrear el código donde se detecta esta excepción y ver si desencadena cualquier evento o establece cualquier estado que le permita detectar esta condición. – Foole

+0

Lo que he decidido es verificar que la conexión esté abierta antes de realizar la solicitud al servidor: if (client.State == CommunicationState.Opened) { client.ServerRequest(); } Si no, entonces tengo un controlador de eventos para manejar este escenario. – paj777

4

Pude replicar su problema y me interesé (ya que necesitaba lo mismo). Incluso investigué una forma de manejar excepciones \ catch chance chance pero lamentablemente no es posible (para código administrado) para .net framework 3.5 y siguientes.

En mi caso, siempre obtengo un System.ServiceModel.CommunicationObjectFaultedException cada vez que algo sale mal en el servicio o cada vez que accedo a un servicio de bajada. Resulta que la declaración de C# using es la causa porque detrás de la escena, la declaración using siempre cierra la instancia del cliente de servicio incluso si ya se encontró una excepción (no salta directamente a la instrucción catch).

Lo que pasa es que la excepción original System.ServiceModel.EndpointNotFoundException será reemplazada por la nueva excepción System.ServiceModel.CommunicationObjectFaultedException cada vez que los using trata de cerrar la instancia de cliente de servicio.

La solución que he hecho es no utilizar la instrucción using modo que siempre que una excepción que se encuentre dentro del bloque try se tirará al instante la excepción de los bloques catch.

Trate de codificar algo como:

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

En lugar de:

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 
} 

y usted será capaz de detectar la excepción en ese momento.

+0

No me gusta no usar 'using', pero +1 de todos modos para la explicación de lo que está sucediendo. – Bobson

3

Eche un vistazo a this post para obtener detalles sobre esta posible solución. El código muestra el uso de un proxy de generación, pero también es válido en ChannelFactory y otros.

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

O, tal como se expresa en su pregunta sin una instrucción using,

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(); 
} 
0

lugar una prueba:

patrón típico

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 

patrón correcto aquí-BE-dragones catch block en el CompletedMethod.

Un ejemplo:

... 
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"); 
     } 
Cuestiones relacionadas