¿Cómo se ejecuta una aplicación de consola .NET?

Considere una aplicación de consola que inicia algunos servicios en un hilo separado. Todo lo que tiene que hacer es esperar que el usuario presione Ctrl + C para apagarlo.

¿Cuál de las siguientes es la mejor manera de hacer esto?

static ManualResetEvent _quitEvent = new ManualResetEvent(false); static void Main() { Console.CancelKeyPress += (sender, eArgs) => { _quitEvent.Set(); eArgs.Cancel = true; }; // kick off asynchronous stuff _quitEvent.WaitOne(); // cleanup/shutdown and quit } 

O esto, usando Thread.Sleep (1):

 static bool _quitFlag = false; static void Main() { Console.CancelKeyPress += delegate { _quitFlag = true; }; // kick off asynchronous stuff while (!_quitFlag) { Thread.Sleep(1); } // cleanup/shutdown and quit } 

siempre quiere evitar el uso de bucles while, especialmente cuando está forzando al código a volver a verificar las variables. Desperdicia recursos de CPU y ralentiza su progtwig.

Definitivamente diría el primero.

Alternativamente, una solución más simple es simplemente:

 Console.ReadLine(); 

Puede hacerlo (y eliminar el controlador de eventos CancelKeyPress ):

 while(!_quitFlag) { var keyInfo = Console.ReadKey(); _quitFlag = keyInfo.Key == ConsoleKey.C && keyInfo.Modifiers == ConsoleModifiers.Control; } 

No estoy seguro de si eso es mejor, pero no me gusta la idea de llamar a Thread.Sleep en un bucle … Creo que es más fácil bloquear la entrada del usuario.

Prefiero usar la aplicación. Ejecutar

 static void Main(string[] args) { //Do your stuff here System.Windows.Forms.Application.Run(); //Cleanup/Before Quit } 

de los documentos:

Comienza a ejecutar un bucle de mensaje de aplicación estándar en el hilo actual, sin un formulario.

Parece que lo estás haciendo más difícil de lo que necesitas. ¿Por qué no simplemente Join al hilo después de haberle indicado que se detenga?

 class Program { static void Main(string[] args) { Worker worker = new Worker(); Thread t = new Thread(worker.DoWork); t.IsBackground = true; t.Start(); while (true) { var keyInfo = Console.ReadKey(); if (keyInfo.Key == ConsoleKey.C && keyInfo.Modifiers == ConsoleModifiers.Control) { worker.KeepGoing = false; break; } } t.Join(); } } class Worker { public bool KeepGoing { get; set; } public Worker() { KeepGoing = true; } public void DoWork() { while (KeepGoing) { Console.WriteLine("Ding"); Thread.Sleep(200); } } } 

De los dos primeros es mejor

 _quitEvent.WaitOne(); 

porque en el segundo, el subproceso se activa cada milisegundo se convertirá en la interrupción del sistema operativo, que es caro

Debería hacerlo como lo haría si estuviera progtwigndo un servicio de Windows. Nunca usarías una statement while sino que usarías un delegado. WaitOne () se usa generalmente mientras se espera que los hilos se deshagan – Thread.Sleep () – no es aconsejable – ¿Ha pensado usar System.Timers.Timer usando ese evento para verificar el evento de apagado?