c# wcf exception proxy using-statement

c# - Excepción en la declaración "using" con WCF no cerrando las conexiones correctamente. ¿Cómo se cierran las conexiones de los clientes de WCF o las que tienen excepciones?



exception proxy (2)

Cierre y eliminación de un servicio WCF

Como esa publicación alude, cierra cuando no hubo excepciones y cancela cuando hay errores. Dispose y, por lo tanto, no se debe utilizar con WCF.

Hay varias preguntas sobre StackOverflow relacionadas con el cierre de conexiones WCF; sin embargo, las respuestas de mayor clasificación se refieren a este blog:

http://marcgravell.blogspot.com/2008/11/dontdontuse-using.html

Tengo un problema con esta técnica cuando configuro un punto de interrupción en el servidor y dejo que el cliente cuelgue durante más de un minuto. (Intento crear una excepción de tiempo de espera)

El problema es que el cliente parece "bloquearse" hasta que el servidor finaliza el procesamiento. Mi suposición es que todo se está limpiando después de la excepción.

Con respecto a TimeOutException , parece que la lógica TimeOutException retry() del cliente continuará reenviando la consulta al servidor una y otra vez, donde puedo ver que el depurador del servidor pone en cola las solicitudes y luego ejecuta cada solicitud en cola al mismo tiempo . Mi código no espera que WCF actúe de esta manera y puede ser la causa de los problemas de corrupción de datos que estoy viendo.

Algo no completa totalmente con esta solución.

¿Cuál es la forma moderna que todo lo abarca de lidiar con fallas y excepciones en un proxy WCF?


Actualizar

Es cierto que esto es un poco de código mundano para escribir. Actualmente prefiero esta respuesta vinculada , y no veo ningún "hackeo" en ese código que pueda causar problemas en el futuro.

Esta es la forma recomendada por Microsoft para manejar llamadas de clientes WCF:

Para obtener más detalles, consulte: Excepciones esperadas

try { ... double result = client.Add(value1, value2); ... client.Close(); } catch (TimeoutException exception) { Console.WriteLine("Got {0}", exception.GetType()); client.Abort(); } catch (CommunicationException exception) { Console.WriteLine("Got {0}", exception.GetType()); client.Abort(); }

Información adicional Tantas personas parecen estar haciendo esta pregunta en WCF que Microsoft incluso creó una muestra dedicada para demostrar cómo manejar las excepciones:

c: / WF_WCF_Samples / WCF / Basic / Client / ExpectedExceptions / CS / client

Descargue la muestra: C # o VB

Teniendo en cuenta que hay tantos problemas que involucran la declaración de uso , (¿acalorado?) Las discusiones internas y los hilos sobre este tema, no voy a perder el tiempo tratando de convertirme en un código vaquero y encontrar una manera más limpia. Simplemente lo absorberé, e implementaré los clientes de WCF de esta forma detallada (aunque de confianza) para mis aplicaciones de servidor.

Fallas adicionales opcionales para atrapar

Muchas excepciones se derivan de CommunicationException y no creo que la mayoría de esas excepciones deban volverse a intentar. Recorrí cada excepción en MSDN y encontré una breve lista de excepciones reintentables (además de TimeOutException anterior). Avíseme si me perdí una excepción que debería volver a intentarse.

Exception mostRecentEx = null; for(int i=0; i<5; i++) // Attempt a maximum of 5 times { try { ... double result = client.Add(value1, value2); ... client.Close(); } // The following is typically thrown on the client when a channel is terminated due to the server closing the connection. catch (ChannelTerminatedException cte) { mostRecentEx = cte; secureSecretService.Abort(); // delay (backoff) and retry Thread.Sleep(1000 * (i + 1)); } // The following is thrown when a remote endpoint could not be found or reached. The endpoint may not be found or // reachable because the remote endpoint is down, the remote endpoint is unreachable, or because the remote network is unreachable. catch (EndpointNotFoundException enfe) { mostRecentEx = enfe; secureSecretService.Abort(); // delay (backoff) and retry Thread.Sleep(1000 * (i + 1)); } // The following exception that is thrown when a server is too busy to accept a message. catch (ServerTooBusyException stbe) { mostRecentEx = stbe; secureSecretService.Abort(); // delay (backoff) and retry Thread.Sleep(1000 * (i + 1)); } catch(Exception ex) { throw ex; // rethrow any other exception not defined here } } if (mostRecentEx != null) { throw new Exception("WCF call failed after 5 retries.", mostRecentEx ); }