[C#] Task.Delay 사용시기, Thread.Sleep 사용시기

Task.DelayThread.Sleep 을 사용할 때 좋은 규칙이 있습니까?

  • 구체적으로, 하나가 다른 것보다 효과적이고 효율적일 수 있도록하는 최소값이 있습니까?
  • 마지막으로 Task.Delay로 인해 비동기 / 대기 상태 시스템에서 컨텍스트 전환이 발생하므로이를 사용하는 오버 헤드가 있습니까?


답변

Thread.Sleep현재 스레드를 차단하려는 경우에 사용하십시오 .

Task.Delay현재 스레드를 차단하지 않고 논리적 지연을 원할 때 사용하십시오 .

이러한 방법에서 효율성이 가장 중요한 문제가되어서는 안됩니다. 실제 실제 사용은 I / O 조작을위한 재시도 타이머로서 밀리 초가 아닌 초 단위입니다.


답변

가장 큰 차이점 Task.Delay와는 Thread.Sleep그가되어 Task.Delay비동기 적으로 실행하기위한 것입니다. Task.Delay동기 코드에서 사용하는 것은 의미가 없습니다 . Thread.Sleep비동기 코드에서 사용하는 것은 매우 나쁜 생각 입니다.

일반적으로 당신은 호출 Task.Delay()await키워드 :

await Task.Delay(5000);

또는 지연 전에 코드를 실행하려면 다음을 수행하십시오.

var sw = new Stopwatch();
sw.Start();
Task delay = Task.Delay(5000);
Console.WriteLine("async: Running for {0} seconds", sw.Elapsed.TotalSeconds);
await delay;

이것이 무엇을 인쇄 할 것 같습니까? 0.0070048 초 동안 실행 await delay위를 Console.WriteLine대신 이동하면 5.0020168 초 동안 실행 중으로 인쇄됩니다.

다음과의 차이점을 살펴 보겠습니다 Thread.Sleep.

class Program
{
    static void Main(string[] args)
    {
        Task delay = asyncTask();
        syncCode();
        delay.Wait();
        Console.ReadLine();
    }

    static async Task asyncTask()
    {
        var sw = new Stopwatch();
        sw.Start();
        Console.WriteLine("async: Starting");
        Task delay = Task.Delay(5000);
        Console.WriteLine("async: Running for {0} seconds", sw.Elapsed.TotalSeconds);
        await delay;
        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");
    }
}

이것이 인쇄 할 내용을 예측해보십시오 …

비동기 : 비동기 시작
: 0.0070048 초 동안 실행
동기화 :
비동기 시작 : 5.0119008 초 동안 실행
비동기 : 완료
동기화 : 5.0020168 초 동안 실행
동기화 : 완료

또한 Thread.Sleep훨씬 더 정확하고 ms 정확도는 실제로 문제가되지 Task.Delay않지만 최소 15-30ms가 걸릴 수 있습니다. 두 함수의 오버 헤드는 ms 정확도와 비교하여 최소입니다 ( Stopwatch더 정확한 것이 필요하면 클래스 사용 ). Thread.Sleep여전히 스레드를 묶고 Task.Delay기다릴 때 다른 작업을 수행하려면 스레드를 해제하십시오.


답변

현재 스레드가 종료되어 사용 Thread.Sleep하고 실행 중이 면을 얻을 수 있습니다 ThreadAbortException. 함께 Task.Delay하면 항상 취소 토큰을 제공하고 우아하게 죽일 수 있습니다. 그게 내가 선택하는 한 가지 이유입니다 Task.Delay. 참조 http://social.technet.microsoft.com/wiki/contents/articles/21177.visual-c-thread-sleep-vs-task-delay.aspx를

또한이 경우 효율성이 가장 중요하지 않다는 데 동의합니다.


답변

무언가를 추가하고 싶습니다. 실제로 Task.Delay타이머 기반 대기 메커니즘입니다. 소스 를 보면 Timer지연을 담당 하는 클래스에 대한 참조를 찾을 수 있습니다. 반면에 Thread.Sleep실제로는 현재 스레드를 잠자기 상태로 만듭니다. 이렇게하면 하나의 스레드 만 차단하고 낭비하게됩니다. 비동기 프로그래밍 모델에서는 Task.Delay()약간의 지연 후에 무언가 (계속)를 원할 경우 항상 사용해야 합니다.


답변