Momento POG: O famoso GOTO
Leonel Fraga de Oliveira 15/04/2009 23:02

Muito “discriminado” pelos programadores mais experientes, e os mais novos raramente usam, a instrução GOTO virou sinônimo de Gambiarra.

goto

Existente desde os primórdios da programação, serve basicamente para saltarmos incondicionalmente para um ponto do programa, geralmente determinado por um label (não, não é o componente de interfaces gráficas que você está pensando não).

Substituído por IF’s e outras estruturas de controle de fluxo, ninguém lembra que ele existe.

Mas até mesmo em C# ele me salvou de algumas :-)

Tive que terminar um Console Application cuja função é verificar uma caixa de e-mail a cada tantos segundos, e ao pressionar a tecla “Q” a aplicação se encerrava.

Verificar a caixa a cada tantos segundos… imediatamente me veio a idéia de instanciar um Timer, coisa que eu fiz: Configurei no método Main() da aplicação o timer e tal.

Só que aí veio um pequeno problema: o método Main() era executado e a aplicação saia do ar.

Me vieram algumas idéias:

1. Fazer a aplicação esperar uma tecla: Coloquei um método ReadKey(), pois assim o fluxo do método Main() ficaria esperando até que o usuário pressionasse uma tecla, porém o Timer ficaria executando em uma thread a parte (isso é automático), mas teria o problema do usuário ir lá, apertar QUALQUER tecla e a aplicação sai do ar.

static void Main(string[] args)
{
	/*Declaração e configuração do timer...*/
	Console.Write("Pressione qualquer tecla para sair...");
	Console.ReadKey();
}

2. Fazer um looping até que uma determinada tecla seja pressionada: Como eu disse acima, somente ao pressionar a tecla “Q” é que o programa deveria sair do ar. Veja como ficou o código:

static void Main(string[] args)
{
    /*Declaração e configuração do timer...*/
    ConsoleKeyInfo k = new ConsoleKeyInfo();
    Console.Write("Pressione 'Q' para sair...");
    while (!k.KeyChar.ToString().ToUpper().Equals("Q"))
    {
        k = Console.ReadKey();
    }
}

O timer continuaria executando em uma thread à parte, porém temos um probleminha: O looping faz o programa consumir praticamente toda a CPU para si! E como o servidor onde vai rodar esse bicho BOMBA, isso é inadmissível.

3. A Solução definitiva: Como “prender” a saída da aplicação a uma determinada tecla, modificando o fluxo do método Main() sem usar um looping? Foi com essa idéia que tive o insight de usar o famigerado GOTO com o auxílio de um if:

static void Main(string[] args)
{
    /*Declaração e configuração do timer...*/

    ConsoleKeyInfo k = new ConsoleKeyInfo();
    Console.Write("Pressione 'Q' para sair...");
    fluxo:
    k = Console.ReadKey();
    if (!k.KeyChar.ToString().ToUpper().Equals("Q"))
    {
        goto fluxo;
    }
}

Como você pode ver, declarei o label fluxo antes da instrução que faz a aplicação guardar uma tecla, e após uma tecla ser pressionada é feita uma verificação: Se for diferente de “Q”, o programa volta para a instrução de aguardar uma tecla.

Com isso, o programa não consome muita CPU e o meu Timer ficou executando em outra thread, e fazendo o que tem que fazer!

PS: Já prevendo, eu sei que para este caso a melhor alternativa seria fazer um Windows Service, porém eu ainda não sei como construir um (e nem tive tempo de dar uma googlada sobre o assunto :-( ). Como o programa em si está em uma biblioteca de classes, a implementação é muito simples, pois é só instanciar a classe e chamar os métodos dentro do evento OnElapsed de um Timer (igual foi feito no Console Application).

Um abraço!

Leonel Fraga de Oliveira Leonel Fraga de Oliveira é formado em Processamento de Dados na Faculdade de Tecnologia de São Paulo (FATEC-SP - 2002) e anteriormente em Técnico em Eletrônica, pela ETE Professor Aprígio Gonzaga (lá em 1999).
Atualmente trabalha como Analista de Sistemas na Prefeitura Municipal de São Caetano do Sul - SP
Tem como hobbies DJing (também trabalha como DJ freelancer) e ciclismo, além da manutenção dos sites NeoMatrix Light e NeoMatrix Tech.
Gosta de música eletrônica, tecnologia, cinema (super fã de Jornada nas Estrelas), gastronomia e outras coisas mais.


Compartilhe nas redes sociais

   

Deixe seu comentário

comments powered by Disqus