Thread.Sleep(2500) 和 Task.Delay(2500).Wait() 的区别

14
我希望您能澄清这个问题。我知道Task.Delay内部将使用计时器,它显然是基于任务的(可等待的),而Thread.Sleep会导致线程被阻塞。但是,调用 .Wait 会导致线程被阻塞吗?
如果不会,那么人们会认为 Task.Delay(2500).Wait() Thread.Sleep(2500)更好。这与此处的SO问题/答案略有不同,因为我正在调用 .Wait()

1
为什么会更好呢? - i3arnon
2
是的,在 Task 上调用 .Wait() 是一个阻塞的调用。从你的角度来看,它们本质上是等价的。 - Glorin Oakenfoot
由于您的2个选项提供了如此相似的功能,我认为您需要澄清“更好”是什么意思。 - Simon MᶜKenzie
这个回答解决了你的问题吗?何时使用Task.Delay,何时使用Thread.Sleep? - T.Todua
2个回答

20

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

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

使用 Task.Delay 的唯一优点是它允许使用 CancellationToken,这样你就可以在需要时取消阻塞。


...但前提是你有另一个正在运行的线程,可以使用CancellationToken,因为主线程将被阻塞。 - Bradley Uffner
2
@BradleyUffner 嗯,你可以创建一个自我取消的令牌(在内部使用计时器)... - i3arnon

7

Thread.Sleep(...) 创建一个事件,在 X 毫秒后唤醒您,然后使您的线程进入休眠状态...在 X 毫秒后,该事件会唤醒您。

Task.Delay(...).Wait() 创建一个事件,在 X 毫秒后启动一个任务,然后将您的线程休眠直到任务完成(使用 Wait)... 在 X 毫秒后,该事件启动任务,任务立即结束,然后唤醒您。

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


"Task.Delay(...).Wait() 会在 X 毫秒后创建一个事件来启动任务,然后将您的线程休眠直到任务完成。这里不会创建任何任务。" - Voo
2
有一个,但是它是空的。Delay返回一个Task对象。 - Guillaume F.
1
是的,表述不太好。没有任务会被“启动”。只有一个任务对象由TaskCompletionSource创建,并在一段时间后更新其状态。 - Voo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接