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.KeyAvailable
o bloqueo Console.ReadKey
. Si bien es cierto que .NET Console
no es muy cooperativo aquí, puede usarlo Task.Run
para avanzar hacia un Async
modo 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 Async
funcionar, lo que significa que, cuando se cae del fondo de su main
función, en lugar de esperar la Async
finalizació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 Async
soporte 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
}
}