2013-06-23 31 views
51

Wiem, że Thread.Sleep blokuje wątek.Thread.Sleep vs Task.Delay?

Ale czy Task.Delay również blokuje? Czy jest to tak jak Timer, który używa jednego wątku dla wszystkich wywołań zwrotnych (gdy nie zachodzą na siebie)?

(this pytanie nie obejmuje różnic)

+2

Tutaj jest trochę [wiki] (http://social.technet.microsoft.com/wiki/contents/articles/21177.visual-c-thread-sleep-vs-task-delay.aspx) z wyróżnieniem demo niektóre różnice w blokowaniu między tymi dwoma. – jxramos

+0

Możliwy duplikat [Thread.Sleep (2500) vs. Task.Delay (2500) .Wait()] (http://stackoverflow.com/questions/34052381/thread-sleep2500-vs-task-delay2500-wait) –

Odpowiedz

51

dokumentacji MSDN jest rozczarowujące, ale decompiling Task.Delay przy użyciu reflektor daje Więcej informacji:

public static Task Delay(int millisecondsDelay, CancellationToken cancellationToken) 
{ 
    if (millisecondsDelay < -1) 
    { 
     throw new ArgumentOutOfRangeException("millisecondsDelay", Environment.GetResourceString("Task_Delay_InvalidMillisecondsDelay")); 
    } 
    if (cancellationToken.IsCancellationRequested) 
    { 
     return FromCancellation(cancellationToken); 
    } 
    if (millisecondsDelay == 0) 
    { 
     return CompletedTask; 
    } 
    DelayPromise state = new DelayPromise(cancellationToken); 
    if (cancellationToken.CanBeCanceled) 
    { 
     state.Registration = cancellationToken.InternalRegisterWithoutEC(delegate (object state) { 
      ((DelayPromise) state).Complete(); 
     }, state); 
    } 
    if (millisecondsDelay != -1) 
    { 
     state.Timer = new Timer(delegate (object state) { 
      ((DelayPromise) state).Complete(); 
     }, state, millisecondsDelay, -1); 
     state.Timer.KeepRootedWhileScheduled(); 
    } 
    return state; 
} 

Zasadniczo metoda ta jest po prostu timer zawinięty wewnątrz zadania. Więc tak, możesz powiedzieć, że to tak jak timer.

+1

Czy blokuje, czy nie? –

+1

@RoyiNamir Nie rozumiem twojego pytania. To zadanie, czy blokuje, czy nie wszystko zależy od sposobu, w jaki go używasz. –

+11

Pomyśl o "poczekaj Task.Delay (1000)" jako asynchronicznej wersji Thread.Sleep (1000), ponieważ nie blokuje. Używam go w narzędziach GUI, kiedy muszę poczekać, ale nie chcę blokować interfejsu lub zżerać wątków. – hko