मेरे पास एक प्रक्रिया है जो अपने स्वयं के धागे में चलती है और इसे अवरुद्ध किए बिना शुरू/बंद कर दिया जा सकता है। यह अंत में एक विंडोज सेवा में जाएगा, लेकिन मैं इसे अब तक कंसोल ऐप में स्थापित कर रहा हूं जब तक कि यह पूरी तरह से बाहर नहीं हो जाता है।लूप के बजाए एक सेमफोर का उपयोग करना। यह अच्छा है या बुरा है?
प्रारंभ करने के लिए कॉल के बाद(), मैं मुख्य प्रोग्राम थ्रेड को ब्लॉक-सी दबाए जाने तक अवरुद्ध करना चाहता हूं। मुझे पता है कि यह काम करेगा:
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
}
}
हालांकि, मुझे ध्वज और मनमानी नींद मूल्य परेशान लगता है। मुझे पता है कि सीपीयू लागत व्यावहारिक रूप से 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();
};
संपादित करें 2:
मैं नोट करना चाहिए यह महत्वपूर्ण है कि यह है कि Stop()
विधि बाहर निकलने पर बुलाया जाता है। @ एडम राल्फ के पास हाइब्रिड कंसोल/सेवा के लिए एक बिल्कुल अच्छा पैटर्न है, लेकिन Q.
यदि आप थोड़ी देर से बच सकते हैं तो मैं कहता हूं कि यह पीछा करने लायक है। – ChaosPandion
बाद वाले प्रोटोटाइप के लिए एक सुधार है। एक उत्पादन आवेदन में मैं पूरे "CTRL + C" ब्रेक विचार से बचूंगा। इसके बजाए धागे को मारने के लिए सिग्नल का प्रयोग करें। जिस तरह से सिग्नल 'सेट() 'शामिल है, अन्य परतों पर निर्भर करता है। अपनी सेवा को डिजाइन करते समय बस इसे ध्यान में रखें। एक साधन जोड़ें, एक विधि की तरह जिसे कॉल किया जा सकता है, बदले में, 'सेट() 'पर कॉल करें। –
@ पी। ब्रायन।मैकी: हालांकि यह एक उत्पादन अनुप्रयोग नहीं है, अगर यह * था, तो क्या यह कम से कम एक गैर-इंटरैक्टिव कंसोल ऐप में Ctrl-C को गहन रूप से संभालने के लिए समझदार नहीं होगा? जैसा कि है, Ctrl-C बाहर निकलने से पहले साफ़ करने के अवसर के बिना प्रोग्राम को बंद कर देगा। आखिरकार, मैं बस सोच रहा था कि "जबकि (ध्वज) थ्रेड के सैमफोर समाधान। सो जाओ (...)" विकल्प। –