我知道在任务中使用Thread.Sleep是一个愚蠢的主意,因为它将阻塞线程池中的该线程。
但是,如果我有一个专用于new Thread(new ThreadStart(Foo))
创建的线程,Task.Delay仍然有意义吗?无论如何都不会使用该线程。我也想知道Task.Delay会产生什么确切效果。它不会使线程进入睡眠状态,因此它将充当自旋等待吗?那比睡觉要糟糕得多。不是吗?
答案 0 :(得分:7)
我很难从问题中弄清楚这里的情况是什么;似乎建议您分配一个线程,然后希望它在一段时间内不执行任何操作。付钱给工人什么都不做是一件奇怪的事。请澄清情况。
要回答您的特定问题:
它不会使线程进入睡眠状态,因此它将充当自旋等待吗?
否。
那会比睡觉更糟。不是吗?
是的,那太可怕了!它会使线程全部陷入瘫痪,但一路上会消耗功率并发热量。您不仅要支付分配线程的开销,而且会主动浪费功率而没有任何好处。您 唯一想要旋转等待的时间是,您等待的时间将比线程数 短得多。旋转等待纳秒或最坏情况(微秒),而不是毫秒。您想旋转等待几条 指令,我们每秒运行数十亿条指令。
基于您的问题,我怀疑(1)您根本不了解Task.Delay的功能,以及(2)您不必要地分配了线程。
让我们首先说一下Task.Delay
的作用。
Task.Delay
立即返回一个表示延迟一定毫秒数任务的对象。
这就是全部。
真的。
它实际上不会延迟任何毫秒数。 它返回代表延迟概念的任务。确保头脑清楚。
如果您问任务是否完成,它会告诉您是否经过了秒数。
如果您将某些功能分配为该任务的延续,则该延续将安排在任务完成后的某个时刻在当前上下文上运行。
await Task.Delay(whatever);
会做什么?
我刚刚说了它的作用。 Task.Delay
返回代表延迟的任务。 await
检查该任务是否完成。如果是这样,则程序将继续正常运行。如果任务未完成,则 await
的位置将成为任务的继续点,并且该方法将返回到其调用方。然后计划在任务完成后的某个时刻在当前上下文上执行继续操作。
为什么您会雇用一名工人来做到这一点,我不知道也不了解。雇用工人完成CPU密集型的工作,在完成之前,他们不会停止对CPU的纳秒级冲击。不要雇用工人一次延迟几毫秒的事情,例如访问磁盘或延迟工作!