何时使用Task.Delay,何时使用Thread.Sleep?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了何时使用Task.Delay,何时使用Thread.Sleep?相关的知识,希望对你有一定的参考价值。
什么时候使用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
是一个基于计时器的等待机制。如果你看看source,你会找到一个Timer
类的参考,它负责延迟。另一方面,Thread.Sleep
实际上使当前线程进入睡眠状态,这样你只是阻塞并浪费一个线程。在异步编程模型中,如果你想在延迟之后发生某些事情(延续),你应该总是使用Task.Delay()
。
以上是关于何时使用Task.Delay,何时使用Thread.Sleep?的主要内容,如果未能解决你的问题,请参考以下文章
我是不是应该始终使用 Task.Delay 而不是 Thread.Sleep? [复制]
Thread.Sleep(2500) 与 Task.Delay(2500).Wait()
REST API 中的 Thread.sleep 与 Task.delay
C#中的Task.Delay()和Thread.Sleep()区别