Pergunta

Se, como eu, você tremer no local de um loop while (true), então você também deve ter pensado muito sobre a melhor maneira de refatorar-lo afastado. Eu vi várias implementações diferentes, nenhum realmente melhor do que qualquer outro, como a combinação de temporizador e delegado.

Então, qual é a melhor maneira que você venha com ou visto refatorar o While temido (True)?

Editar : Como alguns comentários mencionados, a minha intenção era para esta questão a ser um "loop infinito" refatoração, como a execução de um serviço de estilo do Windows, onde as únicas condições parada seria OnStop ou um fatal exceção.

Foi útil?

Solução

Será que realmente precisamos para refatorar while (true) laços? Às vezes é um padrão de codificação ea maioria dos desenvolvedores já se acostumou com essa estrutura. Se você tem que pensar muito sobre como refatorar esse código, você tem certeza que é uma boa idéia para refatorar-lo?

Goto costumava ser uma ovelha negra em padrões de codificação. Eu conheci algoritmos onde Goto feitos o código muito mais legível e mais curto. Às vezes não vale a pena refatorar (ou melhor usar Goto ).

Por outro lado, você pode evitar while (true) a maior parte do tempo.

Outras dicas

A minha preferência seria

start:

   // code goes here

goto start;

Isto expressa mais claramente a intenção. Boa sorte começá-lo após seus padrões de codificação. (Saber o quanto de karma isso vai me custar).

O que é tão temido sobre isso? Tente encontrar uma condição de ruptura comum e refatorar-lo para ser o chefe do loop. Se isso não é possível - Bem.

Quando encontro um (true) loop while, que me diz que quer

  1. a condição de ruptura não é facilmente testado na parte superior (ou inferior) do circuito,
    • existem várias condições de quebra,
    • ou o programador antes estava com preguiça de fator o loop corretamente.

1 e 2 significa que você pode muito bem ficar com while (true). (Eu uso for(;;), mas isso é uma coisa estilo em minha opinião). Eu estou com outro cartaz, por que temer isso? Eu temo laços tortored que saltar através de aros para obter o circuito rolou "corretamente".

Substituir verdadeira com a condição de que você ia usar para sair do loop.

No caso de um serviço ou o fundo da linha, que você pode usar:

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

Por refatorar? E o que é tão "terrível" sobre esta construção? Ele é amplamente usado, e bem compreendido.

Se não está quebrado, não conserte.

A situação "correr para sempre" às ??vezes é parte de uma máquina de estado maior. Muitos dispositivos embarcados (com run-sempre loops) realmente não executar sempre . Eles têm, frequentemente, vários modos de operação e seqüência vontade entre esses modos.

Quando nós construímos controladores de bombas de calor, houve um modo de power-on-self-test (POST), que funcionou por pouco tempo. Em seguida, houve um modo de recolha ambiental preliminar que decorreu até que descobri todas as zonas e termostatos e que-não.

Alguns engenheiros afirmou que o que veio a seguir foi o loop "run-sempre". Não foi realmente muito simples. Foi realmente vários modos de operação que capotou e caiu. Não havia aquecimento e descongelamento e arrefecimento, e em marcha lenta, e outras coisas.

A minha preferência é para tratar um "para sempre" laço como realmente apenas um modo de operação -. Pode haver outras pessoas em algum momento no 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

Em algumas circunstâncias, nada temos visto até agora define someMode para False. Mas eu gosto de fingir que vai haver uma mudança de modo de alguma versão futura.

#define ever 1
for (;ever;)

?

Meh, apenas deixá-lo como é, while (true) é provavelmente tão legível como você está indo para obter ..

errr, para ser um refactoring .....

  • Substitua Infinite Loop com infinita recursão :-)

Bem, se você tem uma linguagem que suporta chamadas de cauda ....

Se você quer que ele continue indefinidamente até que um aborto total de fluxo de programa, não vejo mal qualquer coisa com while (true). Eu encontrei recentemente em um serviço de coleta de dados .NET que combinava while (true) com Thread.sleep para acordar a cada minuto e consultar o serviço de dados de terceiros para novos relatórios. Eu considerei refatoração-lo com um temporizador e um delegado, mas finalmente decidiu que este era o método mais simples e fácil de ler. 9 vezes fora de 10, é um cheiro de código claro, mas quando não há nenhuma condição de saída, por que tornar as coisas mais difíceis?

Eu não me importo quando o loop infinito está contido dentro de uma janela, e morre com a janela.

Pense na Hasselhoff recursão.

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

Aviso:. Sua pilha irá pode ser excesso, dependente da linguagem, otimizador e outras coisas

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top