如何保持.NET控制台应用程序运行?

考虑一个控制台应用程序,它在一个单独的线程中启动一些服务。 所有它需要做的是等待用户按Ctrl + Cclosures它。

以下哪个方法是更好的方法?

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 } 

或者,使用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 } 

你总是要防止使用while循环,特别是当你迫使代码重新检查variables。 它浪费CPU资源,并减慢你的程序。

我肯定会说第一个。

或者,更简单的解决scheme只是:

 Console.ReadLine(); 

你可以做到这一点(并删除CancelKeyPress事件处理程序):

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

不知道这是否更好,但我不喜欢在一个循环中调用Thread.Sleep的想法..我认为它是更干净的阻止用户input。

我更喜欢使用Application.Run

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

从文档:

开始在当前线程上运行一个标准的应用程序消息循环,没有表单。

看起来像你正在努力,比你需要。 为什么不在你发出信号后Join线程?

 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); } } } 

这两个第一个更好

 _quitEvent.WaitOne(); 

因为在第二个线程中,每隔一毫秒就会唤醒一个线程,这个线程将会变成很昂贵的OS中断

你应该这样做,就像你正在编程一个Windows服务。 你永远不会使用while语句,而是使用委托。 通常在等待线程处理时使用WaitOne() – Thread.Sleep() – 不可取 – 您是否想过使用System.Timers.Timer使用该事件来检查closures事件?