c# - startnew - Cuándo usar Task.Delay, cuándo usar Thread.Sleep?
task.run c# (4)
La mayor diferencia entre Task.Delay
y Thread.Sleep
es que Task.Delay
está diseñado para ejecutarse de forma asíncrona. No tiene sentido usar Task.Delay
en código síncrono. Es una MUY mala idea usar Thread.Sleep
en código asíncrono.
Normalmente llamará a Task.Delay()
con la palabra clave Task.Delay()
:
await Task.Delay(5000);
o, si desea ejecutar algún código antes de la demora:
var sw = new Stopwatch();
sw.Start();
Task wait = Task.Delay(5000);
Console.WriteLine("async: Running for {0} seconds", sw.Elapsed.TotalSeconds);
await wait;
Adivina qué imprimirá esto? Corriendo por 0.0070048 segundos. Si movemos la await wait
encima de la Console.WriteLine
lugar, se imprimirá En ejecución durante 5.0020168 segundos.
Veamos la diferencia con Thread.Sleep
:
class Program
{
static void Main(string[] args)
{
Task wait = asyncTask();
syncCode();
wait.Wait();
Console.ReadLine();
}
static async Task asyncTask()
{
var sw = new Stopwatch();
sw.Start();
Console.WriteLine("async: Starting");
Task wait = Task.Delay(5000);
Console.WriteLine("async: Running for {0} seconds", sw.Elapsed.TotalSeconds);
await wait;
Console.WriteLine("async: Running for {0} seconds", sw.Elapsed.TotalSeconds);
Console.WriteLine("async: Done");
}
static void syncCode()
{
var sw = new Stopwatch();
sw.Start();
Console.WriteLine("sync: Starting");
Thread.Sleep(5000);
Console.WriteLine("sync: Running for {0} seconds", sw.Elapsed.TotalSeconds);
Console.WriteLine("sync: Done");
}
}
Trate de predecir lo que esto imprimirá ...
async: comenzando
async: Ejecutando por 0.0070048 segundos
sincronizar: comenzando
async: corriendo por 5.0119008 segundos
async: hecho
sync: funcionando durante 5.0020168 segundos
sincronizar: Hecho
Además, es interesante observar que Thread.Sleep
es mucho más preciso, que la precisión de ms no es realmente un problema, mientras que Task.Delay
puede tardar entre Task.Delay
y Task.Delay
ms como mínimo. La sobrecarga en ambas funciones es mínima en comparación con la precisión de ms que tienen (use la clase de Stopwatch
si necesita algo más preciso). Thread.Sleep
aún vincula tu Thread, Task.Delay
libera para hacer otro trabajo mientras esperas.
¿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 async / await, ¿existe alguna sobrecarga de uso?
Quiero añadir algo. En realidad, Task.Delay
es un mecanismo de espera basado en temporizador. Si observa la source , encontrará una referencia a una clase de Timer
responsable de la demora. Por otro lado, Thread.Sleep
realmente hace que el hilo actual se duerma, de esa manera solo estás bloqueando y desperdiciando un hilo. En el modelo de programación asíncrono, siempre debe usar Task.Delay()
si quiere que algo (continuación) suceda después de algún retraso.
Si el subproceso actual se Thread.Sleep
y utiliza Thread.Sleep
y se está ejecutando, puede obtener una ThreadAbortException
. Con Task.Delay
siempre puedes proporcionar un token de cancelación y matarlo con gracia. Esa es una razón por la que elegiría Task.Delay
. consulte http://social.technet.microsoft.com/wiki/contents/articles/21177.visual-c-thread-sleep-vs-task-delay.aspx
También estoy de acuerdo en que la eficiencia no es de suma importancia en este caso.
Use Thread.Sleep
cuando desee bloquear el hilo actual.
Use 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.