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

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 IFs 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!