2012-05-22 22 views
11

मैं किसी भी फेंकने वाले अपवादों के बारे में विवरण लॉग इन करने के लिए FirstChanceException ईवेंट का उपयोग कर रहा हूं।AppDomain.FirstChanceException और स्टैक ओवरफ़्लो अपवाद

static void Main(string[] args) 
{ 
    AppDomain.CurrentDomain.FirstChanceException += (sender, eventArgs) => 
    { 
     Console.WriteLine("Inside first chance exception."); 
    }; 

    throw new Exception("Exception thrown in main."); 
} 

यह अपेक्षा के अनुसार काम करता है। लेकिन अगर ईवेंट हैंडलर के अंदर एक अपवाद फेंक दिया जाता है, तो घटना को फिर से उठाए जाने के बाद से एक स्टैक ओवरफ़्लो होगा।

static void Main(string[] args) 
{ 
    AppDomain.CurrentDomain.FirstChanceException += (sender, eventArgs) => 
    { 
     throw new Exception("Stackoverflow"); 
    }; 

    throw new Exception("Exception thrown in main."); 
} 

ईवेंट हैंडलर में होने वाले अपवादों को मैं कैसे संभाल सकता हूं?

संपादित करें:

वहाँ सुझाव है कि मैं एक आज़माएं/कैच ब्लॉक में ईवेंट हैंडलर के अंदर कोड लपेट में कुछ जवाब है, लेकिन यह काम नहीं करता क्योंकि घटना अपवाद संभाला जा सकता है पहले उठाया है।

static void Main(string[] args) 
{ 
    AppDomain.CurrentDomain.FirstChanceException += (sender, eventArgs) => 
    { 
     try 
     { 
      throw new Exception("Stackoverflow"); 
     } 
     catch 
     { 
     } 
    }; 

    throw new Exception("Exception thrown in main."); 
} 
+0

बस प्रत्यावर्तन को रोकने के लिए एक bool क्षेत्र का उपयोग करें। –

+0

मुझे नहीं पता कि आप यह क्यों चाहते हैं। पहला मौका अपवाद संभाला जाता है। पृथ्वी पर क्यों आप एक और फेंक देंगे? – leppie

+0

मैं जानबूझकर किसी और को फेंक नहीं रहा हूं। क्या होता है यदि मैं उस त्रुटि को लॉग करने का प्रयास कर रहा हूं और जब मैं उस जानकारी को लॉग करने का प्रयास कर रहा हूं तो अपवाद फेंक दिया जाता है? – nivlam

उत्तर

-1

सामान्य अपवाद आप सभी दूसरों की तरह संभाल कर सकते हैं, लेकिन क्या में विशेष StackOverflow और OutOfMemory अपवाद में के बारे में, वे .NET फ्रेमवर्क में संभाला नहीं जा सकता।

यहाँ देखो: How do I prevent and/or handle a StackOverflowException? (C#)

.नेट फ्रेमवर्क संस्करण 2.0 के साथ शुरू, एक StackOverflowException वस्तु एक कोशिश पकड़ ब्लॉक द्वारा पकड़ा नहीं किया जा सकता है और इसी प्रक्रिया डिफ़ॉल्ट रूप से समाप्त हो जाता है। नतीजतन, उपयोगकर्ताओं को सलाह दी जाती है कि स्टैक ओवरफ़्लो का पता लगाने और रोकने के लिए अपना कोड लिखें। उदाहरण के लिए, यदि आपका एप्लिकेशन रिकर्सन पर निर्भर करता है, तो रिकर्सिव लूप को समाप्त करने के लिए काउंटर या राज्य स्थिति का उपयोग करें।

+0

मैं एक स्टैक ओवरफ्लो अपवाद पकड़ने के लिए नहीं देख रहा हूँ। मैं इसे होने से रोकने के लिए एक रास्ता तलाश रहा हूं। – nivlam

+0

@nivlam: इसे रोकने से रोकने के लिए बस उस फ़ंक्शन को कॉल न करें जो * * रास्ते * में स्टैक ओवरफ़्लो बनाता है। आप किस समाधान के लिए खोज रहे हैं, तो ?? – Tigran

-1

मुझे लगता है कि अपवाद संचालक में एक और try {} catch(){} ब्लॉक मैन्युअल रूप से जोड़ने जैसे मदद मिलेगी अपवाद के अंदर

static void Main(string[] args) 
{ 
    AppDomain.CurrentDomain.FirstChanceException += (sender, eventArgs) => 
    { 
     try { 
      throw new Exception("Stackoverflow"); 
     } catch (Exception e) 
     { 
      // Do something very simple not throwing an exception... 
     } 
    }; 

    throw new Exception("Exception thrown in main."); 
} 
+1

यह काम नहीं करता है। कैच ब्लॉक में अपवाद को संभालने से पहले फर्स्टचेंस अपवाद घटना उठाई जाती है। – nivlam

-1

हैंडल

static void Main(string[] args) { 
    AppDomain.CurrentDomain.FirstChanceException += (sender, eventArgs) => 
    { 
     try{ 
     throw new Exception("Stackoverflow");} catch (Exception ex){/*manual handle*/} 
    }; 
     throw new Exception("Exception thrown in main."); 
} 
0

MSDN लेख आप लिंक किए गए कुछ recommandations बनाता है:

आप सभी अपवादों कि FirstChanceException घटना के लिए ईवेंट हैंडलर में होते हैं संभाल चाहिए। अन्यथा, फर्स्टचेंस अपवाद को दोबारा उठाया जाता है। इसका परिणाम स्टैक ओवरफ़्लो और एप्लिकेशन की समाप्ति हो सकता है। हम अनुशंसा करते हैं कि अपवाद अधिसूचना संसाधित होने पर वर्चुअल मशीन को प्रभावित करने से बाहर की मेमोरी या स्टैक ओवरफ़्लो जैसे बुनियादी ढांचे से संबंधित अपवादों को रखने के लिए आप इस घटना के लिए ईवेंट हैंडलर को बाधित निष्पादन क्षेत्र (सीईआर) के रूप में कार्यान्वित करते हैं।

तो आज़माएं/कैच ब्लॉक के अंदर अपना समारोह लगा, और ब्लॉक से पहले PrepareConstrainedRegion फोन OutOfMemory अपवाद से बचने के लिए: http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.runtimehelpers.prepareconstrainedregions.aspx

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

+0

एएसपी.नेट में कोई भी समस्या प्रदर्शन? मेरे आवेदन _ASP.NET 4.6.1_ के लिए मेरे पास ** डंप उत्पादन ** है। केवल 20 मिनट में _7000 अपवाद_ (*** पहला मौका अपवाद ***) हैं। मुझे *** stackoverflow या outofmemory अपवादों के बिना समस्या का अध्ययन करने के लिए पहले से _first अवसर अपवादों की आवश्यकता है *** – Kiquenet

0

पहले एक प्रतिनिधि के बजाय एक विधि का उपयोग करें, तो विधि नाम

परिभाषित किया जाएगा तो फिर यदि विधि स्टैकट्रेस

यहाँ में पहले से ही है की जाँच करने के Environment.StackTrace का उपयोग कोड का एक टुकड़ा है अपरीक्षित:

static void Main(string[] args) 
{ 
    AppDomain.CurrentDomain.FirstChanceException += handleFirstChanceException; 
} 

private void handleFirstChanceException(object sender, EventArgs eventArgs) 
{ 
    if (Environment.StackTrace.Contains("handleFirstChanceException")) 
     return; 

    // handle 
} 

मुझे लगता है कि इसके बाद के संस्करण काम नहीं करेगा क्योंकि यह हमेशा विधि का नाम शामिल है जाएगा, लेकिन अगर यह 1 से अधिक समय दिखाई देते हैं आप भरोसा कर सकते हैं। साथ ही, यह जांचें कि जब आप रिलीज मोड में संकलित करते हैं, तो इस मामले में आप परेशानी में हैं

+0

क्या होता है जब 'Environment.StackTrace' प्रॉपर्टी गेटटर अपवाद फेंकता है? – hvd

+0

इसे क्यों फेंकना चाहिए? डॉक्टर (http://msdn.microsoft.com/en-us/library/system.environment.stacktrace.aspx) कहता है कि यह केवल एक ArgumentOutOfRangeException फेंक सकता है लेकिन मैं – Fabske

+0

में कोई समस्या नहीं कर सकता था कुछ भी हमेशा 'आउटऑफमेमरी अपवाद' । जो पहली मौका अपवाद ट्रिगर करेगा, और एक और स्टैक ट्रेस पाने का प्रयास करेगा, जो भी विफल हो जाएगा, क्योंकि आप स्मृति से बाहर हैं। – hvd

1

घटनाक्रम यह एक अच्छा तरीका नहीं है, वीबी .NET में आप फर्स्टChanceException ईवेंट हैंडलर के अंदर अपवाद फायरिंग को रोक सकते हैं " त्रुटि पर फिर से शुरू करें "स्टेटमेंट, वीबी 6 से आ रहा है। (मुझे यकीन नहीं है कि सी # में कुछ समान है) इसके अतिरिक्त, आपको इवेंट हैंडलर पर रिकर्सन को here के रूप में वर्णित करना चाहिए। नमूना कोड निम्नलिखित है, जैसा कि अपेक्षित काम करता है।

Sub Main(args As String()) 
    AddHandler AppDomain.CurrentDomain.FirstChanceException, AddressOf FirstChanceExceptionEventHandler 
    Throw New Exception("Exception thrown in main.") 
End Sub 

Private Sub FirstChanceExceptionEventHandler(ByVal source As Object, ByVal e As FirstChanceExceptionEventArgs) 
    On Error Resume Next 

    Dim frames As StackFrame() = New StackTrace(1).GetFrames() 
    Dim currentMethod As MethodBase = MethodBase.GetCurrentMethod() 
    If frames IsNot Nothing AndAlso frames.Any(Function(x) x.GetMethod() = currentMethod) Then 
     Return 
    Else 
     Throw New Exception("Stackoverflow") 
    End If 
End Sub 
4

यह मेरे लिए काम कर रहा है:

private volatile bool _insideFirstChanceExceptionHandler;  

// ... 

AppDomain.CurrentDomain.FirstChanceException += OnFirstChanceException; 

// ... 

private void OnFirstChanceException(object sender, FirstChanceExceptionEventArgs args) 
{ 
    if (_insideFirstChanceExceptionHandler) 
    { 
     // Prevent recursion if an exception is thrown inside this method 
     return; 
    } 

    _insideFirstChanceExceptionHandler = true; 
    try 
    { 
     // Code which may throw an exception 
    } 
    catch 
    { 
     // You have to catch all exceptions inside this method 
    } 
    finally 
    { 
     _insideFirstChanceExceptionHandler = false; 
    } 
} 
+0

यह वास्तव में ऐसा करने का सही तरीका है, इसे स्वीकृत उत्तर चिह्नित किया जाना चाहिए। हालांकि आपको अलग-अलग ऐपडोमेन का ख्याल रखने के लिए कोड को बढ़ाना पड़ सकता है, लेकिन अन्यथा, अच्छा समाधान! – Abel

+0

अच्छा समाधान, आपने मेरा दिन बचाया –

संबंधित मुद्दे