我知道这可能是一个'愚蠢'的问题,但有时候,我只想循环直到条件为假但我不喜欢保持循环为空。所以而不是:
Visible = true;
while(IsRunning)
{
}
Visible = false;
我通常更喜欢:
while(IsRunning)
{
Visible = true;
}
Visible = false;
但是,我有点担心Visible = true;
行的确切情况。运行时是否继续执行该语句,即使它是冗余?这样做甚至可取吗?许多“代码增强”插件不喜欢空的while循环,我真的不明白为什么。
的 SO: 的
有一个空的while循环有什么问题吗?
如上所示的循环是否会产生任何性能影响?
谢谢!
答案 0 :(得分:6)
这称为忙或旋转等待。
主要问题是,你正在阻塞线程,即运行while while循环。如果这个线程是GUI线程,那么它将导致冻结和不负责任的GUI。是的,这会导致性能下降,因为编译器和操作系统都无法知道它们是否可以在循环时以某种方式优化它。
试着像这样制作单循环,看看CPU的一个核心是如何以100%运行的。
执行此操作的正确方法是使用异步编程,在上一个操作完成运行时,通过事件或语言构造(如await)通知代码。
但它通常用于低级系统或语言。 .NET 4.0引入了SpinWait构造,用作有效的线程化sychnronization。
关于你的问题。我相信都不应该使用。它们在调试,性能和代码清晰度方面都存在问题。
答案 1 :(得分:1)
这样做并不是一个好主意。启动应用程序,当它进入此循环时,请查看任务管理器中的CPU使用情况。您会注意到其中一个CPU核心将以满负荷运行。这意味着浪费了能源,而其他一些可能需要执行的程序也没有尽可能多的CPU时间。
有几种方法可以解决这个问题。这里最简单的解决方案是让线程在每个循环传递中休眠几毫秒,如下所示:
Visible = true;
while(IsRunning)
{
Thread.Sleep(50 /* millisec */);
}
Visible = false;
更好的解决方案取决于您的计划究竟在做什么。如果它在另一个线程中加载某些内容,最好使用AutoResetEvent
,或通过锁定或其他thread synchronization mechanism。
答案 2 :(得分:1)
不要在main(UI线程)中执行此操作。尝试查找或制作事件(例如,IsRunningChanged)。
如果您需要在线程中等待,最好使用EventWaitHandle http://msdn.microsoft.com/en-us/library/system.threading.eventwaithandle.eventwaithandle.aspx
但如果您需要等待bool值,您可以
while(IsRunning)
{
Thread.Sleep(10);
}
答案 3 :(得分:1)
嗯..
还有其他解决方案,但如果不了解您的计划,则很难提供建议。但是,您可能希望查看IPC并且通常使用阻塞方法(在单独的线程中调用它们)而不是非阻塞。
阻塞方法暂停你的线程并将控制权交还给操作系统,操作系统将(希望)对CPU时间做一些有用的事情,比如让部分CPU处于休眠状态,节省电力并减少热量输出。