Después de congelar mi aplicación rastreé la causa a un hilo que esperaba en una tarea creada por Task.Delay()
(o TaskEx.Delay()
en .NET 4.0) para la cual proporcionó un TimeSpan
calculado que, debido a un error, en ocasiones se calculó como TimeSpan
con un TotalMilliseconds
de menos de o igual a -1
y mayor que -2
(es decir, en cualquier lugar entre -10000 a -19999 tics, inclusive).¿Por qué Task.Delay() permite un retraso infinito?
Parece que cuando se pasa un negativo TimeSpan
que es -2
milisegundos o inferior, el método genera correctamente un ArgumentOutOfRangeException
, pero cuando se proporciona un intervalo de tiempo negativo del intervalo descrito anteriormente, devuelve un Task
que nunca se completa (mediante el establecimiento de el System.Threading.Timer
subyacente a un dueTime
de -1 que indica el infinito). Eso significa que cualquier continuación establecida en esa tarea nunca se ejecutará, y cualquier hilo defectuoso que ocurra con .Wait()
en ese Task
será bloqueado para siempre.
¿Qué uso posible puede tener un Task
que nunca se completa? ¿Alguien esperaría tal valor de retorno? ¿No debería pasar ningún valor negativo a .Delay()
, incluidos los valores en ese rango especial, arrojar un ArgumentOutOfRangeException
?
El documento MSDN es bastante explícito al permitir -1, por lo que parece que se comporta correctamente. No estoy seguro del caso de uso para esa sobrecarga, pero podría ser una forma de esperar una cancelación "justa" con la sobrecarga que requiere una ficha de cancelación. –
@James: no es explícito al permitir -1, es explícito al no permitir valores inferiores a -1. Ni siquiera dice qué pasará si pasa -1, a diferencia de la documentación de 'System.Threading.Timer'. Casi parece que la lista documentada de excepción se generó automáticamente a partir del código fuente. Y si está esperando una cancelación 'justa', ¿por qué incluso hacer una llamada a 'Task.Delay()'? –
si crees que está roto, presenta un error al conectar. Un documento que dice "menor que -1 no es válido" es explícito (para mí) al decir que -1 es válido. Si la intención fuera -1 como inválida "más bajo que 0 no es válido" hubiera sido más fácil escribir. Como el documento y el código permiten -1, creo que esto es por diseño, pero no duden en enviar un error al conectar (más probable es que el equipo de BCL los procese que un hilo SO aleatorio, creo :) :) –