Cuándo usar la tarea.Delay, cuando usar hilo.¿Dormir?
Hay una(s) buena (s) regla (s) para cuándo usar la tarea .Delay versus Hilo.¿Dormir?
- Específicamente, ¿hay un valor mínimo para prever que uno sea efectivo/eficiente sobre el otro?
- Por último, desde Tarea.El retardo causa el cambio de contexto en una máquina de estado async/await, ¿hay una sobrecarga de usarlo?
5 answers
Use Thread.Sleep
cuando desee bloquear el hilo actual.
Use Task.Delay
cuando desee un retardo 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 están en el orden de segundos en lugar de milisegundos.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-19 23:44:29
La mayor diferencia entre Task.Delay
y Thread.Sleep
es que Task.Delay
está destinado a ejecutarse asincrónicamente. 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ás a Task.Delay()
con la palabra clave await
:
await Task.Delay(5000);
O, si desea ejecutar algún código antes del retraso:
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? Funcionando durante 0.0070048 segundos.
Si movemos el await wait
por encima del Console.WriteLine
en su lugar, se imprimirá Funcionando 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
asíncrona: Funcionando durante 0.0070048 segundos
sincronización: Comenzando
async: Corriendo por 5.0119008 segundos
async: Hecho
sincronización: Funcionando durante 5.0020168 segundos
sincronización: Hecho
También, es interesante notar que Thread.Sleep
es mucho más preciso, la precisión de ms no es realmente un problema, mientras que Task.Delay
puede tomar 15-30ms mínimo. La sobrecarga en ambas funciones es mínima en comparación con la precisión ms que tienen (uso Stopwatch
Class if you need something more accurate). Thread.Sleep
aún ata tu Hilo, Task.Delay
suéltalo para hacer otro trabajo mientras esperas.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-01 11:36:16
Si el subproceso actual está muerto y usas Thread.Sleep
y se está ejecutando, entonces podrías obtener un ThreadAbortException
.
Con Task.Delay
siempre puede proporcionar un token de cancelación y eliminarlo con gracia. Esa es una razón por la que elegiría Task.Delay
. véase 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 primordial en este caso.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-19 06:12:34
Quiero añadir algo.
En realidad, Task.Delay
es un mecanismo de espera basado en temporizador. Si miras la fuente encontrarás una referencia a una clase Timer
que es responsable del retraso. Por otro lado Thread.Sleep
en realidad hace que el hilo actual duerma, de esa manera solo está bloqueando y desperdiciando un hilo. En el modelo de programación asincrónica siempre debe usar Task.Delay()
si desea que algo(continuación) suceda después de algún retraso.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-14 10:16:51
Estas son operaciones funcionalmente equivalentes – simplemente crean una pausa, pero una tarea.El retraso está disponible.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-04 22:49:33