Task.Delay 와 Thread.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()
약간의 지연 후에 무언가 (계속)를 원할 경우 항상 사용해야 합니다.