【问题标题】:Alternatives to Thread.Sleep() for simulating pauses用于模拟暂停的 Thread.Sleep() 的替代品
【发布时间】:2009-09-21 22:47:45
【问题描述】:

所以 Thread.Sleep() 不好 (http://msmvps.com/blogs/peterritchie/archive/2007/04/26/thread-sleep-is-a-sign-of-a-poorly-designed-program.aspx)。

是否有任何推荐的替代方法来模拟程序执行中的暂停?例如循环?虽然我认为这涉及初始化变量、检查布尔条件等方面的大量开销。

谢谢

【问题讨论】:

  • 我想为那篇文章投票,但我不能。 StackOverflow 毁了我的互联网。
  • 我希望那篇文章解释为什么在连续工作循环中使用 100% cpu 是 Thread.Sleep(1) 的首选替代方案。

标签: c#


【解决方案1】:

如果您只想模拟一个暂停(如用于测试目的),我认为 Thread.Sleep 是一种完全有效的方法。另一方面,如果你真的在等待某些东西,某种线程安全的信号机制会更好(检查继承WaitHandle的类型)。

【讨论】:

    【解决方案2】:

    模拟暂停

    “模拟”听起来像是你只会在调试时做的事情。 Thread.Sleep 应该没问题。

    睡眠的主要问题是通常你应该等待特定的事情发生而不是等待任意延迟。

    要注意的另一件事是从 UI 线程调用 Thread.Sleep,这将使 UI 无响应。最好禁用您不希望用户与之交互的 UI 部分,然后使用Timer 控件来实现延迟。

    【讨论】:

    • 这是一个完美的建议!它以我希望的方式在我的程序中起作用。我只是添加了另一个计时器来等待指定的时间,然后再转到程序的另一部分。
    【解决方案3】:

    从您所说的来看,您正在尝试模拟执行中的暂停。

    Thread.Sleep 对此完全有效。甚至您链接的文章也以:

    Thread.Sleep 有它的用途:在 MTA 线程上测试/调试时模拟冗长的操作。

    【讨论】:

      【解决方案4】:

      我不同意Thread.Sleep() 是“坏”的评价。视情况而定。

      在控制台模式程序中,如果您正在等待某些东西,那么让线程休眠可能是非常合适的。甚至可能在一个循环中:检查条件,如果不满足则休眠一会儿,然后重复。

      然而,在图形程序中,通常您不会在主 (GUI) 线程上休眠。这是因为如今的 GUI 界面是使用单个交互式线程设计的。如果你在那个线程上睡觉,你的整个 GUI 会在你睡觉的时候“锁定”。更好的情况可能是使用某种计时器(所有 GUI 框架都有这样的概念)。

      不想想做的一件事是编写一个循环,不断检查某些条件是否为真,甚至不睡觉。这将导致一个 CPU 运行到 100%,因为 CPU 想要尽快完成它的工作。这不仅从用户的角度来看是出乎意料的,而且是不友好的,因为这样的活动会使您实际等待的进程没有足够的周期来完成工作!

      【讨论】:

      • 这就是同步原语的用途。这就是这篇博文的重点。
      • 但是“模拟程序执行中的暂停”并不是同步原语的用途。这就是问题的重点。
      • 但是你写的是可以用来交流的,其实不然。
      • 你可以替换 while(true) { Thread.Sleep(period);做工作(); } 用 WaitHandle.WaitOne(timeout) 代替。
      • 我并不是建议使用睡眠进行交流。我的回答通常对于为什么您可能想要暂停执行的原因是不可知的,而是我试图说睡眠是一个完全有效的 API 调用并且您不想尝试“模拟”通过编写一个无睡眠循环来睡眠。
      【解决方案5】:

      如果您正在等待某些代码或事件发生,您可以使用等待句柄。

      【讨论】:

      • 您甚至可以使用等待句柄代替 Thread.Sleep(time) 来执行周期性逻辑。
      【解决方案6】:

      虽然文章本身值得商榷,但我同意它的开头句子,它解决了您的担忧

      Thread.Sleep 有它的用处:模拟 冗长的操作,而 在 MTA 线程上进行测试/调试。 在 .NET 中没有其他理由使用 它。

      我相信这就是您要问的(模拟暂停),并且是 Thread.Sleep() 的主要用途

      【讨论】:

        【解决方案7】:

        【讨论】:

          【解决方案8】:

          我相信 Raymond Chen 已经建议将线程优先级设置得更低

          http://blogs.msdn.com/oldnewthing/archive/2009/07/27/9849503.aspx

          我不太明白你为什么要经常停下来。为什么不只是以低优先级完成工作呢?当有更重要的事情要做时,您的后台线程将停止做它正在做的任何事情。当有可用的 CPU 时,您的后台线程将尽可能快地完成它的工作(直到具有更高优先级的东西到达)。

          【讨论】:

          • 他的建议是关于睡眠的“第三次”使用 - 减慢操作速度并且不消耗过多的 CPU 时间。问题是关于模拟暂停,这是 Thread.Sleep 的完美用途。文章在另一个答案中讨论的第二种用途是轮询 - 这很糟糕。
          【解决方案9】:

          我敢打赌,在程序员考虑使用 Thread.Sleep() 的大多数情况下,一些使用 events 的简单代码会很好地工作。

          【讨论】:

            猜你喜欢
            • 2018-10-25
            • 1970-01-01
            • 2010-12-30
            • 2016-02-09
            • 1970-01-01
            • 1970-01-01
            • 2016-09-21
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多