如果您像我一样在 While (True) 循环处颤抖,那么您一定也已经认真思考了重构它的最佳方法。我见过几种不同的实现,没有一个真正比其他实现更好,例如计时器和委托组合。

那么,您想出或看到的重构可怕的 While (True) 循环的最佳方法是什么?

编辑: :正如一些评论提到的,我的目的是让这个问题成为一个“无限循环”重构,例如运行 Windows 风格的服务,其中唯一的停止条件是 OnStop 或致命异常。

有帮助吗?

解决方案

我们真的需要重构 while(true)循环吗? 有时它是一个编码标准,大多数开发人员已经习惯了这种结构。如果你必须仔细思考如何重构这段代码,你确定重构它是个好主意吗?

转到曾经是编码标准中的黑羊。我遇到了算法,其中 goto 使代码更具可读性和更短。有时不值得重构(或者更好地使用 goto )。

另一方面,您可以在大多数情况下避免而(true)

其他提示

我的偏好是

start:

   // code goes here

goto start;

这最清楚地表达了意图。祝你好运,超越你的编码标准。 (想知道这将花费多少业力)。

有什么可怕之处呢?尝试找到一个常见的中断条件并将其重构为循环的头部。如果那是不可能的–细

当我遇到 while(true) 循环时,它告诉我

  1. 在循环的顶部(或底部)不容易测试中断条件,
    • 有多个中断条件,
    • 或者以前的程序员太懒而无法正确分解循环。

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;)

嗯,请保持原样,而(真实)可能会像你要的那样清晰......

呃,要重构......

  • 用无限递归替换无限循环:-)

好吧,如果你有一种支持 Tail 调用的语言......

如果您希望它无限期地继续下去,直到程序流完全中止,我认为 while (true) 没有任何问题。我最近在 .NET 数据收集服务中遇到了这种情况,该服务将 while (true) 与 thread.sleep 结合起来,每分钟唤醒一次并轮询第三方数据服务以获取新报告。我考虑用计时器和委托来重构它,但最终认为这是最简单、最容易阅读的方法。十分之九的情况是明显的代码味道,但是当没有退出条件时,为什么要让事情变得更加困难呢?

当无限循环包含在窗口中并且随窗口死亡时,我不介意。

想想Hasselhoff递归。

void whiletrue_sim(void)
  {
    //some code
    whiletrue_sim();
  }

警告:您的堆栈可能会溢出,具体取决于语言,优化程序和其他内容。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top