मैं एक WinForms अनुप्रयोग में सभी 'बिना खंडित' अपवादों को पकड़ने वाला कुछ कैसे बना सकता हूं?


85

अब तक, मैं सिर्फ कार्यक्रम Application.Runमें Program.csप्रवेश बिंदु के चारों ओर एक कोशिश / पकड़ ब्लॉक लगाता हूं । यह डिबग मोड में सभी अपवादों को अच्छी तरह से पकड़ता है, लेकिन जब मैं डिबग मोड के बिना कार्यक्रम चलाता हूं, तो अपवाद अब और नहीं मिलते हैं। मुझे अनहेल्दी अपवाद बॉक्स मिलता है।

मैं ऐसा नहीं चाहता। मैं चाहता हूं कि गैर-डिबग मोड में चलने पर सभी अपवाद पकड़े जाएं। कार्यक्रम के कई सूत्र हैं और उनमें से सभी अपवादों को एक ही हैंडलर द्वारा पकड़ा जाता है; मैं डीबी में अपवादों को लॉग इन करना चाहता हूं। किसी को कैसे करना है में कोई सलाह है?

जवाबों:


110

थ्रेडएक्ससेप्शन प्रलेखन से उदाहरण पर एक नज़र डालें :

public static void Main(string[] args)
{
   // Add the event handler for handling UI thread exceptions to the event.
    Application.ThreadException += new     
  ThreadExceptionEventHandler(ErrorHandlerForm.Form1_UIThreadException);

  // Set the unhandled exception mode to force all Windows Forms errors
  // to go through our handler.
  Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);

  // Add the event handler for handling non-UI thread exceptions to the event. 
  AppDomain.CurrentDomain.UnhandledException += new       
  UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
}

आप डिबगिंग के दौरान अपवादों को नहीं पकड़ सकते हैं, क्योंकि इससे डीबग करना आसान हो जाता है। यह कुछ हद तक एक हैक है, लेकिन इसके लिए आप उपरोक्त कोड को चारों ओर से लपेट सकते हैं

 if (!AppDomain.CurrentDomain.FriendlyName.EndsWith("vshost.exe")) { ... }

डिबगिंग के दौरान अपवादों को पकड़ने से रोकने के लिए।


1
मैंने एक बैकग्राउंड वर्कर बनाया, और डॉर्क इवेंट हैंडलर में मैंने जानबूझकर एक शून्य संदर्भ अपवाद का कारण बना। हालाँकि यह इनकी स्थापना के बावजूद AppDomain.CurrentDomain.UnhandledException द्वारा पकड़ा नहीं गया: Application.ThreadException + = new System.Threading.ThreadExceptionEventHandler (ApplicationhhreadException); Application.SetUnhandledExceptionMode (UnhandledExceptionMode.CatchException); AppDomain.CurrentDomain.UnhandledException + = new UnhandledExceptionEventHandler (CurrentDomain_UnhandledException);
इसहाक बोलिन्जर

4
@IsaacB, पृष्ठभूमि कार्यकर्ता स्वयं अपवादों को पकड़ता है। आप RunCompletedEventArgs.Efror प्रॉपर्टी को देखते हुए, RunWorkerCompleted में भी अपवाद की जांच कर सकते हैं।
कैन गेनर

1
आप इसे अपने मुख्य रूप के ओनलॉड में डालकर अतिरिक्त थ्रेड्स के लिए अपवाद हैंडलिंग का परीक्षण कर सकते हैं। नया थ्रेड () => {थ्रो न्यू एक्ससेप्शन ();}) स्टार्ट ();
कैन गेन्सर

दुर्भाग्य से हैंडलिंग UnhandledException समाप्त करने से आवेदन बंद नहीं होगा :(
Nazar Grynko

7
FriendlyName.EndsWith हैक के बजाय, Debugger.IsAttached जो क्लीनर है की कोशिश करो।
मोल्टेनफ़ॉर्म

27

NET 4 में, कुछ अपवाद अब डिफ़ॉल्ट रूप से नहीं पकड़े गए हैं; ये अपवाद हैं जो निष्पादन की भ्रष्ट स्थिति को इंगित करते हैं, जैसे कि AccessViolationException।

अपने मुख्य विधि के सामने [HandleProcessCorruptedStateException] टैग का उपयोग करने का प्रयास करें, जैसे

using System.Runtime.ExceptionServices.HandleProcessCorruptedStateExceptions

[HandleProcessCorruptedStateExceptions]
public static int Main()
{
    try
    {
        // Catch any exceptions leaking out of the program
        CallMainProgramLoop();
    }
    catch (Exception e) // We could be catching anything here
    {
        System.Console.WriteLine(e.Message);
        return 1;
    }
    return 0;
  } 

मैं उपयोग कर सकते हैं AppDomain.CurrentDomain.UnhandledExceptionऔर Application.ThreadExceptionभी साथ [HandleProcessCorruptedStateExceptions]टैग?
किकेनेट

18

एक अच्छा उदाहरण http://www.csharp-examples.net/catching-unhandled-exception/ पर पाया जा सकता है, मूल रूप से, अपने मुख्य को इसमें बदलें:

static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);
        Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
        AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

        Application.Run(new Form1());
    }

    static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
    {
        MessageBox.Show(e.Exception.Message, "Unhandled Thread Exception");
    }

    static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        MessageBox.Show((e.ExceptionObject as Exception).Message, "Unhandled UI Exception");
    }

9

आप उसके लिए NBug लाइब्रेरी का उपयोग कर सकते हैं । इस तरह न्यूनतम सेटअप के साथ:

NBug.Settings.Destination1 = "Type=Mail;From=me@mycompany.com;To=bugtracker@mycompany.com;SmtpServer=smtp.mycompany.com;";
AppDomain.CurrentDomain.UnhandledException += NBug.Handler.UnhandledException;
Application.ThreadException += NBug.Handler.ThreadException;

आप अपने एप्लिकेशन में सभी अखंडित बगों पर जानकारी एकत्र करना शुरू कर सकते हैं, भले ही वह क्लाइंट्स के लिए तैनात हो। यदि आप तृतीय पक्ष लाइब्रेरी का उपयोग नहीं करना चाहते हैं, तो आपको नीचे दी गई घटनाओं से जुड़ना चाहिए:

// These two should come before enabling visual styles or running the application
AppDomain.CurrentDomain.UnhandledException += ...
Application.ThreadException += ...
...
Application.Run(new Form1());

1
आपका स्वागत है। यदि आपके और भी सवाल हैं ( nbusy.com/forum/f11 ) पर NBug परियोजना चर्चा मंच का उपयोग करें या यहाँ [nbug] टैग का उपयोग करें।
तेमन सोयगुल

बेशक, आप एक "नियमित" इवेंट हैंडलर को अनहैंडल्डलीसेप्शन ईवेंट के लिए भी सब्सक्राइब कर सकते हैं। देखें msdn.microsoft.com/en-us/library/...
neo2862

Win7 + VS10 पर दोस्तों, अगर मैं इन घटनाओं की सदस्यता लेता हूं तो सदस्यता नहीं चलती है, इसके बजाय नियमित विंडोज विस्टा / 7 डायलॉग दिखाता है Check Online for a Solutionया Close the Program.. आदि। लेकिन अगर मैं सदस्यता नहीं लेता हूं, तो मुझे नियमित जेनेरिक .NET अनहेल्ड अपवाद मिलता है। खिड़की। यह दोनों रिलीज और डिबग बिल्ड पर होता है, ने भी सेटिंग की कोशिश की Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);कुछ भी नहीं बदलता है।
गिदोन

@ ग्रिड, अपवादों को संभालने के बाद आपको पर्यावरण के साथ आवेदन से बाहर होना चाहिए। एक्सिट (1); यदि आप त्रुटि विंडो प्रदर्शित नहीं करना चाहते हैं।
तेमन सोयगुल

@ अपने उत्तर के लिए धन्यवाद। मैं अपना स्वयं का त्रुटि फ़ॉर्म दिखाना चाहता हूं और फिर मैं चाहता हूं कि ऐप बाहर निकल जाए। लेकिन ईवेंट सब्सक्रिप्शन कभी नहीं चलता है, यह केवल अपवाद जीत विस्टा / 7 संवाद दिखाता है जब यह अपवादों का सामना करता है। लेकिन अगर मैं जेनेरिक .NET की सदस्यता नहीं लेता हूं तो बिना किसी अपवाद के अपवाद संवाद प्रकट होता है!
गिदोन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.