如何保持.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事件?