Thread.Sleep(2500) 与 Task.Delay(2500).Wait()

Posted

技术标签:

【中文标题】Thread.Sleep(2500) 与 Task.Delay(2500).Wait()【英文标题】:Thread.Sleep(2500) vs. Task.Delay(2500).Wait() 【发布时间】:2015-12-02 20:29:04 【问题描述】:

我想澄清一下。我知道 Task.Delay 将在内部使用 Timer 并且它显然是基于任务的(等待),而 Thread.Sleep 将导致线程被阻塞。但是,在任务上调用.Wait会导致线程被阻塞吗?

如果不是,人们会认为Task.Delay(2500).Wait()Thread.Sleep(2500) 好。这与我称为.Wait() 的SO question/answer here 略有不同。

【问题讨论】:

为什么会更好? 是的,.Wait() 上的 Task 是一个阻塞调用。从您的角度来看,它们本质上是等价的。 您的 2 个选项提供了如此相似的功能,我认为您确实需要澄清“更好”的含义。 【参考方案1】:

在未完成的任务上使用Wait确实会阻塞线程,直到任务完成。

使用Thread.Sleep 更清晰,因为您是显式阻塞线程而不是隐式阻塞任务。

最好使用Task.Delay 的唯一方法是它允许使用CancellationToken,因此您可以根据需要取消阻止。

【讨论】:

...但只有当你有另一个线程正在运行并且可以使用CancellationToken作为主线程时才会被阻塞。 @BradleyUffner 好吧,您可以创建一个自取消令牌(在内部使用计时器)...【参考方案2】:

Thread.Sleep(...) 创建一个事件以在 X 毫秒内唤醒您,然后让您的线程进入睡眠状态……在 X 毫秒内,该事件将您唤醒。

Task.Delay(...).Wait() 创建一个事件以在 X 毫秒内启动一个任务,然后让您的线程休眠直到任务完成(等待)...在 X 毫秒内,事件启动任务,该任务立即结束然后唤醒你起来。

基本上,它们都非常相似。唯一的区别是如果你想从另一个线程中早点醒来,你不会使用相同的方法。

【讨论】:

"Task.Delay(...).Wait() 创建一个事件以在 X 毫秒内启动一个任务,然后让你的线程进入睡眠状态,直到任务完成" 这里没有创建任务. 是的,有一个,但它是空的。 Delay 返回一个 Task 对象。 是的,配方很糟糕。没有任何任务开始。只有一个由 TaskCompletionSource 创建的任务对象,其状态会在一段时间后更新。

以上是关于Thread.Sleep(2500) 与 Task.Delay(2500).Wait()的主要内容,如果未能解决你的问题,请参考以下文章

C#中的Task.Delay()和Thread.Sleep()区别

如果 Task.Delay 优于 Thread.Sleep,为啥本书中的示例使用 Thread.Sleep?

我是不是应该始终使用 Task.Delay 而不是 Thread.Sleep? [复制]

何时使用Task.Delay,何时使用Thread.Sleep?

Thread.Sleep x Task.Delay [重复]

从 Thread.Sleep() 制作 Task.Delay() [重复]