¿Hay buenas reglas para cuándo usar Task.Delay versus Thread.Sleep ?
- Específicamente, ¿hay un valor mínimo para que uno sea efectivo / eficiente sobre el otro?
- Por último, dado que Task.Delay provoca el cambio de contexto en una máquina de estado asíncrono / espera, ¿hay algún gasto adicional por usarlo?

Respuestas:
Úselo
Thread.Sleepcuando desee bloquear el hilo actual.Úselo
Task.Delaycuando desee un retraso lógico sin bloquear el hilo actual.La eficiencia no debe ser una preocupación primordial con estos métodos. Su uso principal en el mundo real es como temporizadores de reintento para operaciones de E / S, que son del orden de segundos en lugar de milisegundos.
fuente
Thread.Sleepbloqueará el hilo actual que causa un cambio de contexto. Si está utilizando un grupo de subprocesos, esto también podría hacer que se asigne un nuevo subproceso. Ambas operaciones son bastante pesadas, mientras que la multitarea cooperativa proporcionada porTask.Delayetc. está diseñada para evitar toda esa sobrecarga, maximizar el rendimiento, permitir la cancelación y proporcionar un código más limpio.onesi: I would useThread.Sleep` para esperar dentro de un método sincrónico. Sin embargo, nunca hago esto en el código de producción; En mi experiencia, todoThread.Sleeplo que he visto ha sido indicativo de algún tipo de problema de diseño que debe corregirse adecuadamente.La mayor diferencia entre
Task.DelayyThread.Sleepes queTask.Delayestá destinado a ejecutarse de forma asincrónica. No tiene sentido usarloTask.Delayen código síncrono. Es una idea MUY mala usarThread.Sleepen código asincrónico.Normalmente llamarás
Task.Delay()con laawaitpalabra clave:o, si desea ejecutar algún código antes del retraso:
¿Adivina qué imprimirá esto? Corriendo por 0.0070048 segundos. Si movemos lo
await delayanteriorConsole.WriteLine, se imprimirá Running durante 5.0020168 segundos.Veamos la diferencia con
Thread.Sleep:Intenta predecir lo que esto imprimirá ...
Además, es interesante notar que
Thread.Sleepes mucho más preciso, la precisión de ms no es realmente un problema, mientras queTask.Delaypuede tomar un mínimo de 15-30 ms. La sobrecarga en ambas funciones es mínima en comparación con la precisión de ms que tienen (useStopwatchClass si necesita algo más preciso).Thread.Sleepaún ata tu hilo,Task.Delaysuéltalo para hacer otro trabajo mientras esperas.fuente
Thread.Sleep()consume un subproceso completo que de otro modo podría usarse en otro lugar. Si se ejecutan muchas tareas con Thread.Sleep (), existe una alta probabilidad de agotar todos los hilos de threadpool y obstaculizar seriamente el rendimiento.asyncmétodos, ya que se recomienda su uso. Básicamente es una mala idea ejecutarThread.Sleep()un hilo de grupo de subprocesos, no es una mala idea en general. Después de todo, hayTaskCreationOptions.LongRunningcuando ir a laTask.Factory.StartNew()ruta (aunque desanimada) .await waitTasl.Delayutiliza el temporizador del sistema. Dado que "El reloj del sistema" marca "a una velocidad constante", la velocidad de marcación del temporizador del sistema es de aproximadamente 16 ms, cualquier retraso que solicite se redondeará a una serie de tics del reloj del sistema, compensado por el tiempo hasta el primer garrapata. Consulte la documentación deTask.Delaymsdn en docs.microsoft.com/en-us/dotnet/api/… y desplácese hacia abajo para ver los comentarios.si el subproceso actual se elimina y lo usa
Thread.Sleepy se está ejecutando, entonces podría obtener unThreadAbortException. ConTask.Delayusted siempre puede proporcionar un token de cancelación y matarlo con gracia. Esa es una razón por la que elegiríaTask.Delay. ver http://social.technet.microsoft.com/wiki/contents/articles/21177.visual-c-thread-sleep-vs-task-delay.aspxTambién estoy de acuerdo en que la eficiencia no es primordial en este caso.
fuente
await Task.Delay(5000). Cuando mato la tarea, obtengoTaskCanceledException(y la suprimo) pero mi hilo sigue vivo. ¡Ordenado! :)Quiero agregar algo En realidad,
Task.Delayes un mecanismo de espera basado en temporizador. Si observa la fuente , encontrará una referencia a unaTimerclase responsable del retraso. Por otro lado, enThread.Sleeprealidad hace que el hilo actual se suspenda, de esa manera solo está bloqueando y desperdiciando un hilo. En el modelo de programación asíncrona, siempre debe usarTask.Delay()si desea que algo (continuación) suceda después de algún retraso.fuente