42
protected override void OnStart(string[] args) 
{ 
    AppDomain.CurrentDomain.UnhandledException += 
     new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); 

    Thread.Sleep(10000); 

    throw new Exception(); 
} 

void CurrentDomain_UnhandledException(object sender, 
             UnhandledExceptionEventArgs e) 
{ 
} 

मैंने अपनी विंडोज सेवा में उपरोक्त कोड में डीबगर संलग्न किया, CurrentDomain_UnhandledException में ब्रेकपॉइंट सेट किया, लेकिन यह कभी हिट नहीं हुआ था। अपवाद यह कहता है कि यह अनचाहे है, और फिर सेवा बंद हो जाती है। मैंने इवेंट हैंडलर में कुछ कोड डालने का भी प्रयास किया, अगर इसे अनुकूलित किया जा रहा था।मैं विंडोज सेवा में .NET UnhandledException हैंडलिंग कैसे स्थापित कर सकता हूं?

क्या यह विंडोज़ सेवा में अनचाहे अपवाद हैंडलिंग स्थापित करने का उचित तरीका नहीं है?

उत्तर

2

बस उत्सुक, आप क्या करने की कोशिश कर रहे हैं: सेवा क्रैशिंग से बचने, या त्रुटियों की रिपोर्ट करना?

रिपोर्टिंग के लिए, मुझे लगता है कि आपकी सबसे अच्छी शर्त शीर्ष-स्तरीय प्रयास/पकड़ विवरण जोड़ने के लिए है। आप उन्हें विंडोज इवेंट लॉग और/या लॉग फ़ाइल में लॉग इन करने का प्रयास कर सकते हैं।

आप ExitCode संपत्ति को गैर-शून्य मान तक सेट भी कर सकते हैं जब तक कि आप सफलतापूर्वक सेवा को रोक नहीं देते। यदि सिस्टम व्यवस्थापक सेवा नियंत्रण कक्ष से आपकी सेवा शुरू करता है, और आपकी सेवा अचानक गैर-शून्य निकास कोड के साथ बंद हो जाती है, तो Windows त्रुटि के विवरण के साथ एक त्रुटि संदेश दिखा सकता है।

+0

डिबगिंग। मैंने सभी अपवादों को पकड़ने की कोशिश की है, लेकिन कोई मुझे किसी तरह से बच रहा है। मुझे लगा कि यह एक और अधिक प्रबंधनीय समाधान होगा। –

+0

क्या ऑनस्टार्ट या ऑनस्टॉप में अपवाद हो रहा है? क्या आपके पास अपवाद के बारे में कोई अन्य जानकारी है? –

9

विंडोज सेवा में आप ऑनस्टार्ट विधि में अधिक कोड नहीं चलाना चाहते हैं। आप चाहते हैं कि आपका सेवा थ्रेड लॉन्च करने के लिए कोड है और फिर वापस आएं।

यदि आप ऐसा करते हैं तो आप अपने सेवा थ्रेड में होने वाले अपवादों को ठीक कर सकते हैं।

उदा।

public static void Start() 
{ 
    AppDomain currentDomain = AppDomain.CurrentDomain; 
    currentDomain.UnhandledException += new UnhandledExceptionEventHandler(currentDomain_UnhandledException); 

    running = true; 
    ThreadStart ts = new ThreadStart(ServiceThreadBody); 
    thread = new Thread(ts); 
    thread.Name = "ServiceThread"; 
    thread.Priority = ThreadPriority.BelowNormal; 
    thread.Start(); 
} 
+0

मुझे हाल ही में एक ऐसा स्थान है जहां मेरी सेवा अभी भी चलती है लेकिन कोई प्रक्रिया नहीं है ... मुझे लगता है कि यह "निगल" अपवादों के कारण हो सकता है। आश्चर्य है कि क्या आपके मुद्दे पर कोई विचार है? http://stackoverflow.com/questions/41618324/windows-service-runs-but-stops-processing-after-two-days –

4

पता इस सूत्र थोड़ा पुराना है, लेकिन सोचा कि यह नेट में Windows सेवाओं के विकास के व्यक्तिगत अनुभव के आधार पर कुछ टिप्पणियां जोड़ने के लिए उपयोगी होगा। सबसे अच्छा तरीका सेवा नियंत्रण प्रबंधक के तहत विकसित होने से बचने के लिए है, जितना आप कर सकते हैं - इसके लिए आपको सरल दोहन की आवश्यकता है जो सेवाओं को शुरू करने के तरीके की नकल करता है - कुछ ऐसा जो आपकी सेवा कक्षा का उदाहरण बना सकता है (कि आप पहले से ही सर्विसबेस से व्युत्पन्न) और अपने ऑनस्टार्ट, ऑनस्टॉप आदि विधियों को कॉल करें। यह दोहन एक कंसोल ऐप या एक विंडोज ऐप हो सकता है जैसा आप चाहते हैं।

यह .NET में सेवा डिबगिंग सेवा स्टार्ट-अप समस्याओं का एकमात्र तरीका है - आपके कोड, विजुअल स्टूडियो और वास्तविक सेवा नियंत्रण प्रबंधक के बीच बातचीत केवल प्रक्रिया को असंभव बनाती है।

एचटीएच।

+0

+1: अपने सभी तर्क को एक अलग पुस्तकालय में कार्यान्वित करें और अपनी सेवा से कॉल करें। विकास/डिबगिंग उद्देश्यों के लिए एक कंसोल एप्लिकेशन से एक ही लाइब्रेरी को कॉल करें। –

+2

मुझे आपका दृष्टिकोण पसंद है, लेकिन सेवा स्टार्टअप समस्याओं को डीबग करने का यह एकमात्र तरीका नहीं है। मैं क्या करता हूं - विशेष रूप से जब उत्पादन वातावरण में सेवाओं को डीबग करना - WinDbg को सेटअप करना है: 1. उस सेवा से संलग्न करें जब उसकी मेजबानी प्रक्रिया शुरू हो जाती है, और 2. एक सुनवाई बंदरगाह खोलें (सेवा अलगाव को दूर करने के लिए आवश्यक)। फिर, अपने उपयोगकर्ता सत्र के तहत चल रहे WinDbg के एक और उदाहरण का उपयोग करके डीबगिंग शुरू करना संभव है। (पहले कथन के रूप में "RequestAdditionalTime" को कॉन्फ़िगर करने योग्य कॉल, या एक रजिस्ट्री कॉन्फ़िगरेशन, सेवा स्टार्टअप समय पर एससीएम enfores की समय सीमा पर काबू पाने में मदद करता है) –

51

मैं इस धागे के लिए देर से आया हूं, लेकिन मैंने सोचा कि यह एक स्पष्टीकरण प्रदान करने लायक हो सकता है जो कि अन्य उत्तरों में से कोई भी नहीं देता है।

कारण यह है कि CurrentDomain_UnhandledException हैंडलर ओपी के कोड नमूने में नहीं मारा जाता है कि OnStart विधि विंडोज सेवा नियंत्रण प्रबंधक से एक प्रारंभ आदेश के जवाब (आदेश प्राप्त हुआ है और ढांचे के द्वारा इस विधि के लिए भेजा जाता है में कहा जाता है सर्विसबेस कार्यान्वयन); OnStart द्वारा फेंक दिया गया कोई अपवाद बेस क्लास में संभाला जाता है, इवेंट लॉग में लॉग किया जाता है, और एससीएम में लौटाए गए त्रुटि स्थिति कोड में अनुवाद किया जाता है। तो अपवाद कभी भी ऐपडोमेन के अनचाहे अपवाद हैंडलर को प्रचारित नहीं करता है।

मुझे लगता है कि आप पाएंगे कि आपकी सेवा में एक कार्यकर्ता थ्रेड से फेंक दिया गया एक अनचाहे अपवाद CurrentDomain_UnhandledException हैंडलर द्वारा पकड़ा जाएगा।

+0

ऐसा लगता है कि यह ServiceBueuedMainCallback विधि ServiceBase पर है जो इस व्यवहार का कारण बनती है। –

2

जब मैं अपनी विंडोज सेवा पर काम कर रहा था, तो यह खुद को विचित्र रूप से पर्याप्त रूप से रोक रहा था। मैंने सोचा कि यह अवांछित अपवाद के कारण था। फिलहाल मैं टेक्स्ट फ़ाइल पर अनचाहे अपवादों को पकड़ रहा हूं। सबसे पहले आपको टेक्स्ट फ़ाइल पर लॉगिंग एक्सापशन के कारण सी स्थानों पर नई फ़ाइल ServiceLog.txt बनाना होगा। नीचे कोडिंग के साथ मुझे लाइन नंबरों के साथ सभी अनचाहे अपवाद मिल गए।

using System.Security.Permissions; 
using System.IO; 

[SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlAppDomain)] 
    protected override void OnStart(string[] args) 
    { AppDomain currentDomain = AppDomain.CurrentDomain; 
     currentDomain.UnhandledException += new UnhandledExceptionEventHandler(MyHandler); 
     ... 
     Your codes... 
     .... 
    } 
    void MyHandler(object sender, UnhandledExceptionEventArgs args) 
    { 
     Exception e = (Exception)args.ExceptionObject; 
     WriteToFile("Simple Service Error on: {0} " + e.Message + e.StackTrace); 
    } 
    private void WriteToFile(string text) 
    { 
     string path = "C:\\ServiceLog.txt"; 
     using (StreamWriter writer = new StreamWriter(path, true)) 
     { 
      writer.WriteLine(string.Format(text, DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss tt"))); 
      writer.Close(); 
     } 
    } 
संबंधित मुद्दे