本文翻译自:When to use Task.Delay, when to use Thread.Sleep?
Are there good rule(s) for when to use Task.Delay versus Thread.Sleep ? 对于何时使用Task.Delay和Thread.Sleep是否有好的规则?
- Specifically, is there a minimum value to provide for one to be effective/efficient over the other? 具体来说,是否存在一个最小值才能使一个方法比另一个方法有效/有效?
- Lastly, since Task.Delay causes context-switching on a async/await state machine, is there an overhead of using it? 最后,由于Task.Delay导致在异步/等待状态机上进行上下文切换,因此使用它会产生开销吗?
#1楼
参考:https://stackoom.com/question/1MGIn/什么时候使用Task-Delay-什么时候使用Thread-Sleep
#2楼
Use Thread.Sleep
when you want to block the current thread. 要阻止当前线程时,请使用Thread.Sleep
。
Use Task.Delay
when you want a logical delay without blocking the current thread. 如果需要逻辑延迟而不阻塞当前线程,请使用Task.Delay
。
Efficiency should not be a paramount concern with these methods. 对于这些方法,效率不应该是最重要的问题。 Their primary real-world use is as retry timers for I/O operations, which are on the order of seconds rather than milliseconds. 它们在现实世界中的主要用途是作为I / O操作的重试计时器,其数量级为秒而不是毫秒。
#3楼
if the current thread is killed and you use Thread.Sleep
and it is executing then you might get a ThreadAbortException
. 如果当前线程被杀死,并且您使用Thread.Sleep
并且正在执行,则可能会收到ThreadAbortException
。 With Task.Delay
you can always provide a cancellation token and gracefully kill it. 使用Task.Delay
您始终可以提供取消令牌并优雅地杀死它。 Thats one reason I would choose Task.Delay
. 那就是我选择Task.Delay
原因Task.Delay
。 see http://social.technet.microsoft.com/wiki/contents/articles/21177.visual-c-thread-sleep-vs-task-delay.aspx 参见http://social.technet.microsoft.com/wiki/contents/articles/21177.visual-c-thread-sleep-vs-task-delay.aspx
I also agree efficiency is not paramount in this case. 我也同意在这种情况下效率不是最重要的。
#4楼
The biggest difference between Task.Delay
and Thread.Sleep
is that Task.Delay
is intended to run asynchronously. Task.Delay
和Thread.Sleep
之间的最大区别是Task.Delay
旨在异步运行。 It does not make sense to use Task.Delay
in synchronous code. 在同步代码中使用Task.Delay
没有意义。 It is a VERY bad idea to use Thread.Sleep
in asynchronous code. 在异步代码中使用Thread.Sleep
是一个非常糟糕的主意。
Normally you will call Task.Delay()
with the await
keyword: 通常,您将使用await
关键字调用Task.Delay()
:
await Task.Delay(5000);
or, if you want to run some code before the delay: 或者,如果您想在延迟之前运行一些代码:
var sw = new Stopwatch();
sw.Start();
Task delay = Task.Delay(5000);
Console.WriteLine("async: Running for {0} seconds", sw.Elapsed.TotalSeconds);
await delay;
Guess what this will print? 猜猜这将打印什么? Running for 0.0070048 seconds. 运行0.0070048秒。 If we move the await delay
above the Console.WriteLine
instead, it will print Running for 5.0020168 seconds. 如果将await delay
移至Console.WriteLine
上方,它将显示“运行”为5.0020168秒。
Let's look at the difference with Thread.Sleep
: 让我们看看与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");}
}
Try to predict what this will print... 尝试预测将要打印的内容...
async: Starting 异步:开始
async: Running for 0.0070048 seconds 异步:运行0.0070048秒
sync: Starting 同步:开始
async: Running for 5.0119008 seconds 异步:运行5.0119008秒
async: Done 异步:完成
sync: Running for 5.0020168 seconds 同步:运行5.0020168秒
sync: Done 同步:完成
Also, it is interesting to notice that Thread.Sleep
is far more accurate, ms accuracy is not really a problem, while Task.Delay
can take 15-30ms minimal. 另外,有趣的是, Thread.Sleep
准确性要高得多,ms的准确性并不是真正的问题,而Task.Delay
占用时间最少为15-30ms。 The overhead on both functions is minimal compared to the ms accuracy they have (use Stopwatch
Class if you need something more accurate). 与它们具有的ms精度相比,这两个函数的开销是最小的(如果您需要更精确的信息,请使用Stopwatch
Class)。 Thread.Sleep
still ties up your Thread, Task.Delay
release it to do other work while you wait. Thread.Sleep
仍然占用您的线程, Task.Delay
释放它以便在您等待时进行其他工作。
#5楼
I want to add something. 我要添加一些东西。 Actually, Task.Delay
is a timer based wait mechanism. 实际上, Task.Delay
是基于计时器的等待机制。 If you look at the source you would find a reference to a Timer
class which is responsible for the delay. 如果您查看源代码 ,则会发现对造成延迟的Timer
类的引用。 On the other hand Thread.Sleep
actually makes current thread to sleep, that way you are just blocking and wasting one thread. 另一方面, Thread.Sleep
实际上使当前线程进入睡眠状态,这样您就只能阻塞并浪费一个线程。 In async programming model you should always use Task.Delay()
if you want something(continuation) happen after some delay. 在异步编程模型中,如果希望延迟后发生某些事情(继续),则应始终使用Task.Delay()
。