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

Posted

技术标签:

【中文标题】如果 Task.Delay 优于 Thread.Sleep,为啥本书中的示例使用 Thread.Sleep?【英文标题】:If Task.Delay is to be prefered over Thread.Sleep, why examples in this book use Thread.Sleep?如果 Task.Delay 优于 Thread.Sleep,为什么本书中的示例使用 Thread.Sleep? 【发布时间】:2015-12-07 07:53:32 【问题描述】:

我正在阅读考试参考书 70-483:Wouter de Kort 的 C# 编程。 作者没有明确提到 C# 的版本,但我猜是 5.0,因为他大量使用了 async/await 关键字。

本书中的例子只使用了Thread.Sleep(),没有使用Task.Delay()

Parallel.For(0, 10, i =>

    Thread.Sleep(1000);
);

,

Task.Run(() =>

    bag.Add(42);
    Thread.Sleep(1000);
    bag.Add(21);
);

等等等等……

从this 等其他阅读/SO 问题中,我认为

await Task.Delay(1000)

在并行上下文中通常应该比

Thread.Sleep(1000)

因为 Task.Delay 使其线程不受阻碍,从而允许其他任务在其上执行。 我刚刚按了 Ctrl-F 键,但没有找到 Task.Delay 的一次出现! 我对来自互联网的社区意见和 Microsoft 官方书籍感到困惑。如果 Task.Delay 是一种很好的做法,为什么这本书没有以任何方式解决它? 还是我错过了什么?

【问题讨论】:

或许最好问问书的作者? 为了使用 Task.Delay(1000) 你必须使用 'await' 它强制你的方法是异步的。有时这不是一个好方法。但是您始终可以不受限制地使用 Thread.Sleep()。 Task.Delay 只是 Thread.Sleep 的等待版本,原因正是您所说的,因此线程资源被释放以安排其他工作。简而言之,书籍代码往往比较容易遵循,但可能会在奇怪的地方丢球。在线查看本书的勘误表(如果有),并查看其他来源,例如文章或博客文章,以获得进一步的意见和解释。没有一本书是良好编程实践的唯一真理来源,有时一本书会遗漏或出错。 【参考方案1】:

other question 处理真实世界的代码;你书中的代码示例是完全不同的。

代码示例:

Thread.Sleep 适合您想要阻塞当前线程 - 即,您正在模拟一些同步/受 CPU 限制的工作。

Task.Delay 适合您想要阻塞当前线程 - 即,您正在模拟一些异步/I/O 绑定工作。

对于您发布的特定示例(Parallel.ForTask.Run 中的代码),我认为Thread.Sleep 是最合适的。 Parallel.ForTask.Run 专门用于在不同线程上运行 CPU 绑定代码,因此 Thread.Sleep 的同步“占位符”是正确的。

请注意,在实际代码中,Thread.SleepTask.Delay 的任何“占位符”用法都将替换为实际代码。

在实际代码中,Task.Delay 对于延迟重试等事情仍然有用。 Thread.Sleep 不应出现在实际代码中。

【讨论】:

先生,感谢您为我解决问题。我误解了 Thread.Sleep 是为了模拟 CPU-Bound 工作。现在一切都说得通了。【参考方案2】:

考试 70-483 适用于 Visual Studio 2012,当时 C# 没有 async/await。

另外,Thread.Sleep() 只是用来指示正在完成的工作。

【讨论】:

async/await 在书中进行了解释和使用,正如我在问题中所写的那样。另外我认为考试是针对语言的,而不是 IDE。

以上是关于如果 Task.Delay 优于 Thread.Sleep,为啥本书中的示例使用 Thread.Sleep?的主要内容,如果未能解决你的问题,请参考以下文章

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

等待 Task.Delay() 与 Task.Delay().Wait()

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

Task.Delay 使用注意事项

为啥 scheduleAtFixedRate(task, delay, period) 不能按计划工作?

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