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

看起来你有一些工作线程。更好地完成这些任务,他们在WhenAllWhenAny 上使用.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?

REST API 中的 Thread.sleep 与 Task.delay

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