2011-02-11 14 views
19

Recientemente hemos descubierto que WCF no admite operaciones de caducidad en el lado del servicio (nota, servicio lado, no del lado del cliente). Mientras el cliente desconecta después del tiempo especificado, nuestras pruebas han demostrado que para netNamedPipeBinding, netTcpBinding y basicHttpBinding, el tiempo de espera que especifiquemos hará que la operación de servicio se detenga una vez que se haya invocado. A continuación se presentan las configuraciones de unión específicos que probamos:¿Por qué WCF no admite tiempos de espera de servicio?

<bindings> 
    <netNamedPipeBinding> 
    <binding name="TestServiceBindingConfigurationNamedPipe" 
      receiveTimeout="00:00:05" 
      sendTimeout="00:00:05" 
      closeTimeout="00:00:05" 
      openTimeout="00:00:05" /> 
    </netNamedPipeBinding> 
    <netTcpBinding> 
    <binding name="TestServiceBindingConfigurationTcp" 
      receiveTimeout="00:00:05" 
      sendTimeout="00:00:05" 
      closeTimeout="00:00:05" 
      openTimeout="00:00:05" /> 
    </netTcpBinding> 
    <basicHttpBinding> 
    <binding name="TestServiceBindingConfigurationBasicHttp" 
      receiveTimeout="00:00:05" 
      sendTimeout="00:00:05" 
      closeTimeout="00:00:05" 
      openTimeout="00:00:05" /> 
    </basicHttpBinding> 
</bindings> 

Nuestra implementación del servicio de prueba es el siguiente:

public class TestServiceImpl : ITestService 
{ 
    public TestResult TestIt(TestArgs args) 
    { 
     var stopwatch = new Stopwatch(); 
     stopwatch.Start(); 

     // this is a contrived example, but it shows that WCF never stops this thread 
     while (true) 
     { 
      Console.WriteLine("{0}> I'm running forever...", stopwatch.Elapsed); 
     } 

     return new TestResult {Result = "Args were " + args.Args}; 
    } 
} 

Usando netNamedPipeBinding y netTcpBinding, nuestra aplicación cliente tendría tiempo de espera después de 5 segundos, pero el servicio se continuar corriendo indefinidamente

Esto hace que mi pregunta (s) - ¿es esto un error? ¿Hay alguna razón específica por la cual WCF no quisiera desconectar los servicios si se ejecutan más de lo esperado?

Desde mi punto de vista, algunos de los posibles aspectos negativos con este son:

  1. El límite predeterminado de instancias de servicio es 10. Por lo tanto, si usted tiene mal código en su servicio que se ejecuta siempre y es golpear 10 veces, su servicio se apagará por completo; no se aceptan nuevas conexiones
  2. No hay visibilidad sobre el hecho de que los servicios se ejecutan para siempre, sin registro personalizado o posiblemente con contadores de rendimiento
  3. Cualquier recurso que esté siendo utilizado por la llamada de servicio puede mantenerse indefinidamente (fila de SQL, página, y bloqueos de tabla, por ejemplo) si no hay otros mecanismos para agotar el tiempo de espera de la operación.

Respuesta

8

Si tiene un código incorrecto que se ejecuta para siempre, el tiempo de espera puede empeorar las cosas. ¡Repare el código incorrecto si es posible! Vea el artículo de Eric Lippert, Careful with that axe, sobre este tipo de situaciones.

Si esto está en desarrollo, puede intentar configurar un System.Threading.Timer que llame a serviceCallThread.Abort() dentro de la implementación de su servicio. Sin embargo, asegúrese de haber desarmado completamente el temporizador antes de regresar; este enfoque es increíblemente propenso a errores, debido a una combinación de problemas de simultaneidad, no posee el hilo al que llega la llamada de servicio, comportamiento extraño de ThreadAbortException, y los problemas que Eric explica sobre la terminación ciega del código que se ha ido en las malas hierbas.

+0

Lo que queremos es visibilidad del código incorrecto que se ejecuta para siempre. Preferiríamos que se cancelara y se lanzara una TimeoutException antes de que potencialmente consuma CPU sin la visibilidad para decirnos que tenemos un código incorrecto para corregir. –

+1

Sí, quiero decir que tiene sentido deshacerse del código que se ejecuta demasiado tiempo. ¿Pero qué pasa cuando no esperas que se ejecute para siempre?¿Cómo sabrá que el servicio todavía se está ejecutando y en qué estado se encuentra cuando todos los clientes se desconectaron por mucho tiempo? – Jab

+0

En cuanto a tener un temporizador para abortar el hilo de servicio, eso es exactamente lo que hemos terminado de implementar. Parte de la razón por la que hago la pregunta es porque realmente no me siento cómodo al escribir este código porque, como dijiste, es "increíblemente propenso a errores". ¡Sigo esperando haber perdido una línea de configuración en alguna parte! –

0

¿Qué hay de:

<system.web> 
    <httpRuntime executionTimeout="inSeconds"/> 
</system.web> 
+2

Eso no funcionaría para servicios autohospedados, ¿o sí? –

2

me he dado cuenta de este problema a mí mismo ... No puedo pensar en una buena razón para que no incluirán la operación del lado del servicio de tiempos de espera como parte de la plataforma.

Cuestiones relacionadas