13

如果像我一样,你在 While (True) 循环的位置发抖,那么你也一定已经思考了很长时间并努力考虑重构它的最佳方法。我见过几种不同的实现,没有一个比其他的更好,例如计时器和委托组合。

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

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

4

12 回答 12

64

我的偏好是

start:

   // code goes here

goto start;

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

于 2008-10-28T20:02:23.643 回答
27

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

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

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

于 2008-10-28T20:22:22.633 回答
23

有什么好害怕的?尝试找到一个常见的中断条件并将其重构为循环的头部。如果那不可能——很好。

于 2008-10-28T19:10:38.457 回答
18

当我遇到 while(true) 循环时,这告诉我要么

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

1 和 2 意味着你不妨坚持使用 while(true)。(我使用for(;;),但在我看来这是一种风格。)我和另一张海报在一起,为什么害怕这个?我害怕扭曲的循环会跳过箍以使循环“正确”滚动。

于 2008-10-28T19:18:47.350 回答
14

将 True 替换为您要用于跳出循环的条件。

在服务或后台线程的情况下,您可以使用:

volatile bool m_shutdown = false;
void Run()
{
    while (!m_shutdown)
    { ... }
}
于 2008-10-28T19:13:03.897 回答
13

为什么要重构?这个结构有什么“可怕”的?它被广泛使用,并且很好理解。

如果它没有坏,就不要修理它。

于 2008-10-28T19:33:24.853 回答
8

“永远运行”的情况有时是更大状态机的一部分。许多嵌入式设备(带有永远运行的循环)并没有真正永远运行。它们通常有几种操作模式,并且会在这些模式之间排序。

当我们构建热泵控制器时,有一个开机自检 (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

在某些情况下,到目前为止,我们所看到的任何内容都不会设置someModeFalse. 但我喜欢假装在未来的某个版本中会有模式改变。

于 2008-10-28T19:23:17.793 回答
7
#define ever 1
for (;ever;)

?

嗯,就让它保持原样吧,而(真的)可能和你想得到的一样清晰......

于 2008-10-28T19:51:38.657 回答
5

errr,要进行重构.....

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

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

于 2008-10-28T19:14:58.310 回答
3

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

于 2008-10-28T19:22:02.053 回答
1

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

想想哈塞尔霍夫递归。

于 2008-10-28T19:35:55.940 回答
-2
void whiletrue_sim(void)
  {
    //some code
    whiletrue_sim();
  }

警告:您的堆栈可能会溢出。

于 2016-05-17T22:12:27.923 回答