Thread.Sleep x Task.Delay [重复]
Posted
技术标签:
【中文标题】Thread.Sleep x Task.Delay [重复]【英文标题】:Thread.Sleep x Task.Delay [duplicate] 【发布时间】:2021-12-22 17:12:43 【问题描述】:Task.Delay 和 Thread.Sleep 方法的内存消耗不同,我都用过,答案有很大的性能差异。有人知道为什么吗?
带有线程的代码
private void EncerrarWorkers()
foreach (BackgroundWorker worker in Workers)
worker.CancelAsync();
//Encerra os bots
Model.BotsClose();
for (int indexRobo = 0; indexRobo < Workers.Count(); indexRobo++)
if (Model.IsBotClosed(indexRobo))
continue;
Thread.Sleep(5000);
indexRobo--;
任务代码
private void EncerrarWorkers()
foreach (BackgroundWorker worker in Workers)
worker.CancelAsync();
//Encerra os bots
Model.BotsClose();
for (int indexRobo = 0; indexRobo < Workers.Count(); indexRobo++)
if (Model.IsBotClosed(indexRobo))
continue;
Task.Delay(5000);
indexRobo--;
两者都包含在 Windows 窗体的方法中。
利用代码块的性能差异: enter image description here
【问题讨论】:
您的意思是在没有await
的情况下使用Task.Delay
?因为它可能不会做你想让它做的事情。
【参考方案1】:
他们做的事情完全不同。
Thread.Sleep
导致当前正在执行的线程在给定的时间内停止运行。它可能不会消耗额外的内存或做太多的处理,但它在整个睡眠期间使用系统线程,这是一个有限的资源。您可能会饿死您的线程应用程序,或者导致在其他地方创建另一个线程,这会对性能产生很大影响。但是,如果该线程是您计算机上唯一运行的线程,则效果很好。
Task.Delay
创建一个任务,该任务将在给定的时间内处于休眠状态,然后完成。如果您在异步方法中使用,这允许您将线程返回给调用者,调用者可以将其用于其他事情,直到计时器结束。当您有多个线程时,这会更有效,例如在 Web 服务器环境中或执行大量数据库读取。但是,您必须使用await
,否则任务会被创建但随后会被忽略,因此它不会延迟任何事情。并且要使用await,您必须在异步堆栈中的异步方法中。你可以在任务上调用Wait()
,但这仍然会锁定线程,所以此时最好使用Sleep
。
看起来你有一些工作线程。更好地完成这些任务,他们在WhenAll
或WhenAny
上使用.WaitAll
等到实际完成。
【讨论】:
'它在整个睡眠期间使用系统线程,这有很多开销'...什么开销?什么开销? @MartinJames。改写。它们通常具有至少 1MB 的堆栈分配以及用于保存状态的额外内存,但是一旦线程运行,就已经分配了这些内存。因此,可能会创建一个新线程,这是潜在的性能问题以上是关于Thread.Sleep x Task.Delay [重复]的主要内容,如果未能解决你的问题,请参考以下文章
Thread.Sleep(2500) 与 Task.Delay(2500).Wait()
如果 Task.Delay 优于 Thread.Sleep,为啥本书中的示例使用 Thread.Sleep?
从 Thread.Sleep() 制作 Task.Delay() [重复]
何时使用Task.Delay,何时使用Thread.Sleep?