Pregunta

Si, como yo, tiemblas en el sitio de un bucle While (Verdadero), entonces también debes haber pensado mucho sobre la mejor manera de refactorizarlo. He visto varias implementaciones diferentes, ninguna realmente mejor que ninguna otra, como el timer & amp; combinación de delegados.

Entonces, ¿cuál es la mejor manera en la que se te ocurrió o has visto refactorizar el temido bucle While (verdadero)?

Editar : Como mencioné en algunos comentarios, mi intención era que esta pregunta fuera un " bucle infinito " refactorización, como ejecutar un servicio de estilo de Windows donde las únicas condiciones de detención serían OnStop o una excepción fatal.

¿Fue útil?

Solución

¿Realmente necesitamos refactorizar while (true) bucles? A veces es un estándar de codificación y la mayoría de los desarrolladores se han acostumbrado a esta estructura. Si tiene que pensar mucho en cómo refactorizar este código, ¿está seguro de que es una buena idea refactorizarlo?

Goto solía ser una oveja negra en los estándares de codificación. Me he encontrado con algoritmos donde goto hizo que el código fuera mucho más legible y más corto. A veces no vale la pena refactorizar (o mejor usar goto ).

Por otra parte, puedes evitar while (true) la mayor parte del tiempo.

Otros consejos

Mi preferencia sería

start:

   // code goes here

goto start;

Esto expresa más claramente la intención. Buena suerte superando tus estándares de codificación. (Me pregunto cuánto karma me va a costar).

¿Qué tiene tanto miedo? Intente encontrar una condición de ruptura común y refactorice para que sea la cabeza del bucle. Si eso no es posible & # 8211; bien.

Cuando encuentro un bucle while (verdadero), eso me dice cualquiera de las dos

  1. la condición de ruptura no se prueba fácilmente en la parte superior (o inferior) del bucle,
    • hay múltiples condiciones de ruptura,
    • o el programador anterior era demasiado perezoso para factorizar el bucle correctamente.

1 y 2 significa que también puede quedarse con while (verdadero). (Utilizo para (;;) , pero eso es algo relacionado con el estilo en mi opinión). Estoy con otro póster, ¿por qué temer esto? Temo los bucles tortuosos que saltan a través de aros para hacer que se enrute el bucle "correctamente".

Reemplaza True con la condición que ibas a usar para salir del bucle.

En el caso de un servicio o subproceso en segundo plano, puede usar:

volatile bool m_shutdown = false;
void Run()
{
    while (!m_shutdown)
    { ... }
}

¿Por qué refactorizar? Y lo que es tan " terrible " sobre este constructo? Es ampliamente utilizado y bien entendido.

Si no está roto, no lo arregles.

El " corriendo para siempre " La situación es a veces parte de una máquina de estado más grande. Muchos dispositivos integrados (con ciclos de ejecución para siempre) no se ejecutan para siempre . A menudo tienen varios modos de funcionamiento y se secuenciarán entre esos modos.

Cuando construimos controladores de bomba de calor, hubo un modo de encendido en autoprueba (POST) que se ejecutó durante un tiempo. Luego hubo un modo de recolección ambiental preliminar que se ejecutó hasta que descubrimos todas las zonas y los termostatos y lo que no.

Algunos ingenieros afirmaron que lo siguiente fue el " run-forever " lazo. No era realmente tan simple. En realidad, fueron varios modos de funcionamiento que se voltearon y se cayeron. Había calefacción, descongelación, refrigeración, ralentí y otras cosas.

Mi preferencia es tratar un " siempre " bucle como realmente solo un modo de funcionamiento, puede haber otros en algún momento en el futuro.

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

En algunas circunstancias, nada de lo que hemos visto hasta ahora establece someMode en False . Pero me gusta fingir que habrá un cambio de modo en alguna versión futura.

#define ever 1
for (;ever;)

?

Meh, simplemente déjalo como está, mientras que (verdadero) es probablemente tan legible como vas a obtener ...

errr, para ser una refactorización .....

  • Reemplazar bucle infinito con recursión infinita :-)

bueno, si tienes un idioma que admita llamadas Tail ...

Si desea que continúe indefinidamente hasta un aborto total del flujo del programa, no veo nada de malo en while (verdadero). Lo encontré recientemente en un servicio de recopilación de datos .NET que combinaba while (true) con thread.sleep para despertarse cada minuto y sondear el servicio de datos de terceros para nuevos informes. Consideré refactorizarlo con un temporizador y un delegado, pero finalmente decidí que este era el método más simple y más fácil de leer. 9 veces de cada 10 es un claro olor a código, pero cuando no hay una condición de salida, ¿por qué hacer las cosas más difíciles?

No me importa cuando el bucle infinito está contenido dentro de una ventana y muere con la ventana.

Piensa en la recursión de Hasselhoff.

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

Advertencia: su pila puede estar desbordada, dependiendo del idioma, el optimizador y otras cosas.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top