Abordar casos que algunas de las otras respuestas no manejan bien:
- Sensible : ejecución directa del código de manejo de pulsación de tecla; evita los caprichos de las encuestas o retrasos en el bloqueo
- Opcionalidad : la pulsación de tecla global es opcional ; de lo contrario, la aplicación debería salir normalmente
- Separación de preocupaciones : código de escucha menos invasivo; funciona independientemente del código de la aplicación de consola normal.
Muchas de las soluciones en esta página implican sondeo Console.KeyAvailableo bloqueo Console.ReadKey. Si bien es cierto que .NET Consoleno es muy cooperativo aquí, puede usarlo Task.Runpara avanzar hacia un Asyncmodo de escucha más moderno .
El problema principal a tener en cuenta es que, de manera predeterminada, el subproceso de la consola no está configurado para Asyncfuncionar, lo que significa que, cuando se cae del fondo de su mainfunción, en lugar de esperar la Asyncfinalización, su AppDoman y el proceso finalizarán . Una forma adecuada de abordar esto sería utilizar el AsyncContext de Stephen Cleary para establecer un Asyncsoporte completo en su programa de consola de un solo subproceso. Pero para casos más simples, como esperar una pulsación de tecla, instalar un trampolín completo puede ser excesivo.
El siguiente ejemplo sería para un programa de consola utilizado en algún tipo de archivo por lotes iterativo. En este caso, cuando el programa termina con su trabajo, normalmente debería salir sin necesidad de presionar una tecla, y luego permitimos presionar una tecla opcional para evitar que la aplicación salga. Podemos pausar el ciclo para examinar cosas, posiblemente reanudar, o usar la pausa como un 'punto de control' conocido en el que se puede salir limpiamente del archivo por lotes.
static void Main(String[] args)
{
Console.WriteLine("Press any key to prevent exit...");
var tHold = Task.Run(() => Console.ReadKey(true));
// ... do your console app activity ...
if (tHold.IsCompleted)
{
#if false // For the 'hold' state, you can simply halt forever...
Console.WriteLine("Holding.");
Thread.Sleep(Timeout.Infinite);
#else // ...or allow continuing to exit
while (Console.KeyAvailable)
Console.ReadKey(true); // flush/consume any extras
Console.WriteLine("Holding. Press 'Esc' to exit.");
while (Console.ReadKey(true).Key != ConsoleKey.Escape)
;
#endif
}
}