¿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.Sleep
cuando desee bloquear el hilo actual.Úselo
Task.Delay
cuando 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.Sleep
bloqueará 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.Delay
etc. 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 use
Thread.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.Sleep
lo que he visto ha sido indicativo de algún tipo de problema de diseño que debe corregirse adecuadamente.La mayor diferencia entre
Task.Delay
yThread.Sleep
es queTask.Delay
está destinado a ejecutarse de forma asincrónica. No tiene sentido usarloTask.Delay
en código síncrono. Es una idea MUY mala usarThread.Sleep
en código asincrónico.Normalmente llamarás
Task.Delay()
con laawait
palabra 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 delay
anteriorConsole.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.Sleep
es mucho más preciso, la precisión de ms no es realmente un problema, mientras queTask.Delay
puede 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 (useStopwatch
Class si necesita algo más preciso).Thread.Sleep
aún ata tu hilo,Task.Delay
sué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.async
mé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.LongRunning
cuando ir a laTask.Factory.StartNew()
ruta (aunque desanimada) .await wait
Tasl.Delay
utiliza 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.Delay
msdn 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.Sleep
y se está ejecutando, entonces podría obtener unThreadAbortException
. ConTask.Delay
usted 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.Delay
es un mecanismo de espera basado en temporizador. Si observa la fuente , encontrará una referencia a unaTimer
clase responsable del retraso. Por otro lado, enThread.Sleep
realidad 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