【问题标题】:What is the effect of having an empty while loop?有一个空的while循环有什么影响?
【发布时间】:2012-08-02 07:15:21
【问题描述】:

我知道这可能是一个“愚蠢”的问题,但有时,我只想循环直到条件为假,但我不喜欢保持循环为空。所以而不是

Visible = true;
while(IsRunning)
{
}
Visible = false;

我通常更喜欢

while(IsRunning)
{
    Visible = true;
}
Visible = false;

但是,我有点担心Visible = true; 行到底发生了什么。即使它是冗余,运行时是否会继续执行该语句?这样做甚至可取吗?许多“代码增强”插件不喜欢空的while循环,我真的不明白为什么。

所以:

  • 空的while循环有什么问题吗?

  • 如上所示的循环是否会对性能产生影响?

谢谢!

【问题讨论】:

  • 称为busy-wait循环,通常用于等待某个条件变为真假后再继续执行程序
  • 我不明白你为什么要这么做。我假设 IsRunning 将由另一个线程设置......那么你为什么不干脆分离另一个线程并加入()呢?这更清晰,块也一样。
  • 一些早期的计算机设计有一个专用的处理器指令来处理这样的代码:HCF。保持并着火。
  • 检查条件的空循环就像一个孩子不断问“我们到了吗?我们到了吗?我们到了吗?”在一次汽车旅行中。您希望您的程序和孩子直接进入睡眠状态,直到条件变为真。

标签: c# performance loops while-loop


【解决方案1】:

这称为忙或旋转等待。

主要问题是,您阻塞了正在运行此 while 循环的线程。如果这个线程是GUI线程,那么它会导致冻结和不负责任的GUI。是的,这会导致性能损失,因为编译器和操作系统都不知道他们是否可以以某种方式优化这个 while 循环。

尝试像这样进行单循环,看看你的 CPU 的一个核心是如何以 100% 运行的。

正确的做法是使用异步编程,当前一个操作完成运行时,您的代码会通过事件或语言构造(如等待)得到通知。

但它通常用于低级系统或语言。 .NET 4.0 引入了SpinWait 构造,用作高效的线程同步。

关于你的问题。我相信两者都不应该使用。它们在调试、性能和代码清晰度方面都有问题。

【讨论】:

  • 不一定。你也可以做一些'while(DoSomething){}',它不会让处理器能力旋转。例如,DoSomething 可以是步骤结束时的清理资源,并且在清理之前不应继续。 .net 中的一些 ConcurrentThingies 不提供迭代器,因此 TryTake 或其他东西可以在 while 表达式中。在某些示例中您使用了一段时间,但表达式本身会起作用。所以它只需要处理能力......
  • @Offler 你的意思是 DoSomething() 可能是一种方法?因为这不是问题的意义所在。
  • 是的,因为Many 'code-enhancements' plugins don't like empty while loops, and I don't really understand why.Is there anything wrong with having an empty while loop? 这两个句子更通用。甚至 'IsRunning' 也是一个属性,它实际上可以在它的 getter 方法中使用 Threads/sleeps 等做很多事情,因此没有人能真正判断 CPU 是否会达到 100% ..
【解决方案2】:

这样做不是一个好主意。启动应用程序,当它进入这个循环时,在任务管理器中查看 CPU 使用率。您会注意到其中一个 CPU 内核将满负荷运行。这意味着能源被浪费了,而其他一些可能需要执行的程序将没有尽可能多的 CPU 时间。

有几种方法可以解决这个问题。这里最简单的解决方案是在每个循环过程中让线程休眠几毫秒,如下所示:

Visible = true;
while(IsRunning)
{
    Thread.Sleep(50 /* millisec */);
}
Visible = false;

更好的解决方案取决于您的程序到底在做什么。如果它在另一个线程中加载某些内容,最好使用AutoResetEvent,或通过锁定,或其他thread synchronization mechanism

【讨论】:

    【解决方案3】:

    不要在主线程(UI 线程)中执行此操作。尝试查找或制作事件(例如 IsRunningChanged)。

    如果您需要在线程中等待,最好使用 EventWaitHandle http://msdn.microsoft.com/en-us/library/system.threading.eventwaithandle.eventwaithandle.aspx

    但如果你需要等待布尔值,你可以这样做

    while(IsRunning)
    {
        Thread.Sleep(10);
    }
    

    【讨论】:

      【解决方案4】:

      嗯..

      • 是的,一个空的 while 循环通常被视为一件坏事,尽管也有一些有用的情况。
      • 是的,CPU 将执行您的冗余语句
      • 不,您不应该这样做。它使用了 100% 的 CPU,这没什么用。

      有其他解决方案,但在不了解您的程序的情况下很难给出建议。但是,您可能想查看 IPC 并通常使用阻塞方法(在单独的线程中调用它们)而不是非阻塞。

      阻塞方法会暂停你的线程并将控制权交还给操作系统,这将(希望)对 CPU 时间做一些有用的事情,比如让部分 CPU 进入睡眠状态、节省电力和减少热量输出。

      【讨论】:

        猜你喜欢
        • 2020-02-16
        • 1970-01-01
        • 2018-04-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-02
        • 2015-02-22
        相关资源
        最近更新 更多