我已經/停止,在它自己的線程中運行,並且可以啓動的進程不會阻塞。這將最終進入Windows服務,但我現在將它設置在控制檯應用程序中,直到完全充實爲止。使用信號量而不是while循環。這是好還是壞?
後調用start()方法,我想主程序線程阻塞,直到按Ctrl-C。我知道這將工作:
public static void Main(string[] args)
{
bool keepGoing = true;
var service = new Service();
System.Console.TreatControlCAsInput = false;
System.Console.CancelKeyPress += delegate(object sender, ConsoleCancelEventArgs e)
{
e.Cancel = true;
service.Stop();
keepGoing = false; // Break the while loop below
};
service.Start();
while(keepGoing)
{
Thread.Sleep(100); // 100 is arbitrary
}
}
但是,我覺得標誌和任意睡眠值麻煩。我知道,CPU的成本是在while循環實際上是0,但我寧願有一個「硬」塊只要按Ctrl-C處理程序完成後釋放。我設計了下面的內容,使用信號量來阻止,直到匿名Ctrl-C處理程序完成:
public static void Main(string[] args)
{
var service = new Service();
var s = new Semaphore(1, 1);
System.Console.TreatControlCAsInput = false;
System.Console.CancelKeyPress += delegate(object sender, ConsoleCancelEventArgs e)
{
e.Cancel = true;
service.Stop();
s.Release(); // This will allow the program to conclude below
};
service.Start();
s.WaitOne(); // This will not block
s.WaitOne(); // This will block w/o CPU usage until the sempahore is released
}
這是不好的設計?這是否過分矯枉過正?危險嗎?
編輯:
我也掛鉤AppDomain.CurrentDomain.UnhandledException如下:
AppDomain.CurrentDomain.UnhandledException += delegate {
service.Stop();
s.Release();
};
編輯第二:
我要指出,這是關鍵在退出時調用方法Stop()
。 @Adam拉爾夫對混合控制檯/服務一個非常好的模式,但回答Q.
如果你能避免while循環我說,這是值得追求的。 – ChaosPandion
對於後者的原型設計有很大的改進。在生產應用程序中,我會避免整個「CTRL + C」突破想法。改用信號來殺死線程。信號是「Set()」的方式取決於涉及的其他層。在設計服務時請記住這一點。添加一個方法,就像可以調用的方法一樣,調用'Set()'。 –
@ P.Brian。Mackey:雖然這不是一個生產應用程序,但如果它*是*,在非交互式控制檯應用程序中,至少要優雅地處理Ctrl-C是否審慎?事實上,Ctrl-C只會關閉程序而沒有機會在退出之前進行清理。最終,我只是想知道信號量解決方案的「while(標誌)Thread.Sleep(...)」選項。 –