.net - receivetimeout - wcf timeout c#
¿Por qué WCF no soporta los tiempos de espera del lado del servicio? (3)
Recientemente hemos descubierto que WCF no admite el tiempo de espera de las operaciones en el lado del servicio (nota, lado del servicio , no del lado del cliente). Mientras el cliente se 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 muestran las configuraciones de enlace específicas que probamos:
<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 se ve así:
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};
}
}
Al usar netNamedPipeBinding y netTcpBinding, nuestra aplicación cliente se agotaría luego de 5 segundos, pero el servicio continuaría ejecutándose indefinidamente.
Eso trae a mi (s) pregunta (s): ¿ es esto un error? ¿Hay alguna razón específica por la que WCF no querría cancelar los servicios si se ejecutan durante más tiempo del esperado?
Desde mi perspectiva, algunos de los posibles problemas negativos incluyen:
- El límite predeterminado de las instancias de servicio es 10. Por lo tanto, si tiene un código erróneo en su servicio que se ejecuta para siempre y se lo toca 10 veces, su servicio se cerrará por completo; No se aceptan nuevas conexiones.
- No hay ninguna visibilidad sobre el hecho de que los servicios se ejecutan para siempre, salvo el registro personalizado o posiblemente el uso de contadores de rendimiento.
- Cualquier recurso que esté utilizando la llamada de servicio puede mantenerse indefinidamente (por ejemplo, los bloqueos de fila, página y tabla de SQL) si no hay otros mecanismos para suspender el tiempo de la operación.
Qué pasa:
<system.web>
<httpRuntime executionTimeout="inSeconds"/>
</system.web>
Si tiene un código incorrecto que se ejecuta para siempre, el tiempo de espera puede empeorar las cosas. ¡Arregla el código malo si es posible! Vea el artículo de Eric Lippert, Cuidado con ese hacha , 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 concurrencia, que no posee el hilo en el que llega la llamada de servicio, el comportamiento extraño de ThreadAbortException
y el temas que Eric explica sobre el código de terminación a ciegas que se ha disparado en la maleza.
Yo mismo he notado este problema ... No puedo pensar en una buena razón por la que no incluyan los tiempos de espera de las operaciones del lado del servicio como parte de la plataforma.