2009-08-06 5 views
14

Tengo una aplicación de cliente que intenta cada 10 segundos enviar un mensaje a través de un servicio web de WCF. Esta aplicación cliente estará en una computadora a bordo de un barco, que sabemos tendrá conectividad irregular a Internet. Me gustaría que la aplicación intente enviar datos a través del servicio y, si no puede, ponerlos en cola hasta que pueda enviarlos a través del servicio.Recuperación de una CommunicationObjectFaultedException en WCF

Para probar esta configuración, inicio la aplicación cliente y el servicio web (ambos en mi máquina local), y todo funciona bien. Intento simular la mala conexión a Internet matando el servicio web y reinicándolo. Tan pronto como mato el servicio, comienzo a recibir CommunicationObjectFaultedExceptions, que se espera. Pero después de reiniciar el servicio, sigo obteniendo esas excepciones.

Estoy bastante seguro de que hay algo que no entiendo acerca del paradigma del servicio web, pero no sé qué es eso. ¿Alguien puede ofrecer asesoramiento sobre si esta configuración es factible o no y, de ser así, cómo resolver este problema (es decir, restablecer el canal de comunicaciones con el servicio web)?

Gracias!

Klay

Respuesta

33

proxies de servicio de cliente no pueden ser reutilizados una vez que han criticado. Debe deshacerse del antiguo y recrear uno nuevo.

También debe asegurarse de cerrar correctamente el proxy de servicio al cliente. Es posible que un proxy del servicio WCF arroje una excepción al cerrar, y si esto sucede, la conexión no se cierra, por lo que debe cancelarla. Use el patrón "try {Close}/catch {Abort}". También tenga en cuenta que el método de eliminación de llamadas se acerca (y, por lo tanto, puede arrojar una excepción de la disposición), por lo que no puede utilizar simplemente un uso como con clases desechables normales.

Por ejemplo:

try 
{ 
    if (yourServiceProxy != null) 
    { 
     if (yourServiceProxy.State != CommunicationState.Faulted) 
     { 
      yourServiceProxy.Close(); 
     } 
     else 
     { 
      yourServiceProxy.Abort(); 
     } 
    } 
} 
catch (CommunicationException) 
{ 
    // Communication exceptions are normal when 
    // closing the connection. 
    yourServiceProxy.Abort(); 
} 
catch (TimeoutException) 
{ 
    // Timeout exceptions are normal when closing 
    // the connection. 
    yourServiceProxy.Abort(); 
} 
catch (Exception) 
{ 
    // Any other exception and you should 
    // abort the connection and rethrow to 
    // allow the exception to bubble upwards. 
    yourServiceProxy.Abort(); 
    throw; 
} 
finally 
{ 
    // This is just to stop you from trying to 
    // close it again (with the null check at the start). 
    // This may not be necessary depending on 
    // your architecture. 
    yourServiceProxy = null; 
} 

No es un artículo de blog sobre este here

+0

10 si pudiera - wow, este comportamiento es totalmente bajo el radar, nunca se habrían resuelto qué estaba pasando si no hubiera tropezado con esta respuesta. –

+0

¡Bravo! Implementé una versión de esto como un método de extensión: TryDispose en la clase proxy para su uso por parte de otros. –

+0

@ Moby's Stunt Double: ¿puede compartir su código? – RichardHowells

Cuestiones relacionadas