如果您像我一样,在 While (True) 循环处颤抖,那么您也一定已经认真思考了重构它的最佳方法。 我见过几种不同的实现,没有一个比其他实现更好,例如计时器和委托组合。
那么您想出或看到的重构可怕的 While (True) 循环的最佳方法是什么?
编辑:正如一些评论提到的,我的目的是让这个问题成为一个“无限循环”重构,例如运行 Windows 风格的服务,其中唯一的停止条件是 OnStop 或致命异常。
我的偏好是
start:
// code goes here
goto start;
这最清楚地表达了意图。 祝你好运,让它通过你的编码标准。 (不知道这会让我付出多少业力)。
我们真的需要重构 while(true) 循环吗? 有时它是一种编码标准,大多数开发人员已经习惯了这种结构。如果你必须认真思考如何重构这段代码,你确定重构它是个好主意吗?
Goto曾经是编码标准中的害群之马。我遇到过一些算法,其中 goto 使代码更具可读性和更短。有时并不值得重构(或者最好使用 goto)。
另一方面,大多数时候你可以避免 while(true)。
有什么好害怕的?尝试找到一个常见的中断条件并将其重构为循环的头部。如果那不可能——那好吧。
当我遇到 while(true) 循环时,这会告诉我
1 和 2 意味着你最好还是坚持使用 while(true)。 (我使用
for(;;)
,但在我看来这是一种风格。)我和另一张海报在一起,为什么害怕这个? 我害怕那些扭曲的循环,它会跳过铁环,让循环“正确地”滚动。
为什么要重构? 这个构造有何“可怕”之处? 它被广泛使用,并且很好理解。
如果它没有坏,就不要修理它。
将 True 替换为您要用来跳出循环的条件。
对于服务或后台线程,您可以使用:
volatile bool m_shutdown = false;
void Run()
{
while (!m_shutdown)
{ ... }
}
“永远运行”的情况有时是更大状态机的一部分。 许多嵌入式设备(具有永远运行循环)并不真正运行永远。 它们通常有多种操作模式,并会在这些模式之间排序。
当我们构建热泵控制器时,有一个运行一段时间的开机自检(POST)模式。 然后是一个初步的环境收集模式,直到我们弄清楚所有区域和恒温器以及其他什么。
一些工程师声称接下来发生的是“永远运行”循环。 事情其实没那么简单。 实际上是几种运营模式的反复变换。 有加热、除霜、冷却、怠速和其他东西。
我的偏好是将“永远”循环视为实际上只是一种操作模式 - 将来的某个时候可能还会有其他模式。
someMode= True
while someMode:
try:
... do stuff ...
except SomeException, e:
log.exception( e )
# will keep running
except OtherException, e:
log.info( "stopping now" )
someMode= False
在某些情况下,到目前为止我们还没有看到将
someMode
设置为 False
。 但我喜欢假装在未来的版本中会有模式更改。
#define ever 1
for (;ever;)
?
嗯,就让它保持原样,而 (true) 可能与你所得到的一样清晰..
errr,要重构......
好吧,如果你有一种支持 Tail 调用的语言......
如果你希望它无限期地继续下去,直到程序流完全中止,我认为 while (true) 没有任何问题。 我最近在 .NET 数据收集服务中遇到了这种情况,该服务将 while (true) 与 thread.sleep 结合起来,每分钟唤醒一次并轮询第三方数据服务以获取新报告。 我考虑用计时器和委托来重构它,但最终认为这是最简单、最容易阅读的方法。 十分之九的情况是明显的代码味道,但是当没有退出条件时,为什么要让事情变得更加困难呢?
当无限循环包含在窗口内并随窗口一起终止时,我不介意。
想想哈塞尔霍夫递归。
void whiletrue_sim(void)
{
//some code
whiletrue_sim();
}
警告:您的堆栈可能会溢出。