2016-05-25 6 views
7

मैं एक WinForm आवेदन C# जहाँ मैं Program.cs में एक try-catch ब्लॉक डाल दिया, कार्यक्रम प्रविष्टि में में लिखा, static void Main विधि है, है ना इस तरह आवेदन की शुरुआत में है:क्या सी # WinForm स्थिर शून्य मुख्य अपवाद को पकड़ नहीं सकता है?

using System; 
using System.IO; 
using System.Windows.Forms; 

namespace T5ShortestTime { 
    static class Program { 
     /// <summary> 
     /// The main entry point for the application. 
     /// </summary> 
     [STAThread] 
     static void Main() { 
      try { 
       Application.EnableVisualStyles(); 
       Application.SetCompatibleTextRenderingDefault(false); 
       Application.Run(new T5ShortestTimeForm()); 
      } catch (Exception e) { 
       string errordir = Path.Combine(Application.StartupPath, "errorlog"); 
       string errorlog = Path.Combine(errordir, DateTime.Now.ToString("yyyyMMdd_HHmmss_fff") + ".txt"); 
       if (!Directory.Exists(errordir)) 
        Directory.CreateDirectory(errordir);     
       File.WriteAllText(errorlog, e.ToString());    
      } 
     } 
    } 
} 

आप देख सकते हैं , Application को try-catch ब्लॉक में रखा गया है और catch ब्लॉक में, एकमात्र चीज यह है कि त्रुटि लॉग फ़ाइल बनाना है।

अब, अब तक बहुत अच्छा है। मेरा आवेदन अच्छी तरह से चल रहा है और यदि मुझे कोई दुर्घटना आती है, तो अंतिम Exception को try-catch ब्लॉक द्वारा कैप्चर किया जाना चाहिए और त्रुटि लॉग फ़ाइल में संग्रहीत किया जाना चाहिए।

लेकिन, जैसा कि मैं थोड़ी देर के लिए मेरा कार्यक्रम चलाने के लिए, मैं एक बिना क्रिया का अपवाद (null संदर्भ) मिलता है। मुझे आश्चर्य है कि अपवाद त्रुटि लॉग फ़ाइल नहीं बनाता है।

अब, this post से पता चलता है कि यह संभवतः ThreadException या HandleProcessCorruptedStateExceptions (दो सबसे upvoted जवाब) के कारण होता है, लेकिन मेरे मामले एक सरल null संदर्भ अपवाद पता चलता है:

Problem signature: 
    Problem Event Name: CLR20r3 
    Problem Signature 01: T5ShortestTime.exe 
    Problem Signature 02: 2.8.3.1 
    Problem Signature 03: 5743e646 
    Problem Signature 04: T5ShortestTime 
    Problem Signature 05: 2.8.3.1 
    Problem Signature 06: 5743e646 
    Problem Signature 07: 182 
    Problem Signature 08: 1b 
    Problem Signature 09: System.NullReferenceException 
    OS Version: 6.3.9600.2.0.0.272.7 
    Locale ID: 1033 
    Additional Information 1: bb91 
    Additional Information 2: bb91a371df830534902ec94577ebb4a3 
    Additional Information 3: aba1 
    Additional Information 4: aba1ed7202d796d19b974eec93d89ec2 

Read our privacy statement online: 
    http://go.microsoft.com/fwlink/?linkid=280262 

If the online privacy statement is not available, please read our privacy statement offline: 
    C:\Windows\system32\en-US\erofflps.txt 

कि क्यों हो सकता है?

+2

ऐसा नहीं है कि आप वैश्विक अपवाद हैंडलर कैसे बनाते हैं। 'लिंक' अनुभाग में, इस पृष्ठ के दाईं ओर देखें। स्वीकार्य उत्तर आपको बताता है कि क्या करना है। – jmcilhinney

+0

@jmcilhinney आपका मतलब 'थ्रेडएक्सप्शन' है? – Ian

+0

उदाहरण में, // एक नया धागा शुरू करें, विंडोज फॉर्म से अलग, जो अपवाद फेंक देगा। 'निजी शून्य बटन 2_Click (ऑब्जेक्ट प्रेषक, System.EventArgs ई) { थ्रेडस्टार्ट newThreadStart = नया थ्रेडस्टार्ट (newThread_Execute); नया थ्रेड = नया थ्रेड (नया थ्रेडस्टार्ट); newThread.Start(); } 'जो जानबूझकर एक नए धागे में अपवाद को संभालता है। लेकिन क्या यह 'थ्रेडएक्सप्शन' के बजाय 'शून्य' संदर्भ अपवाद (मेरे मामले की तरह) बनाता है (यह इस प्रकार होना चाहिए - है ना?)? – Ian

उत्तर

5

पिछले अपवाद कोशिश कैच ब्लॉक

कि क्या होने वाला नहीं है द्वारा कब्जा कर लिया जाना चाहिए। एक मामले को छोड़कर, जब आप अपने प्रोग्राम को डीबगर संलग्न के साथ चलाते हैं। तो आप निश्चित रूप से यह मानने में उलझ गए कि यह काम करेगा, हर कोई हमेशा कुछ समय के लिए अपने कार्यक्रम को F5 के साथ चलाने शुरू कर देता है।

आवेदन। रुन() के पास कोड में बैक-स्टॉप है जो घटनाओं को बढ़ाता है, एप्लिकेशन को उठाता है/कोशिश करता है। थ्रेड अपवाद घटना जब एक ईवेंट हैंडलर एक अनचाहे अपवाद फेंकता है। वह बैक-स्टॉप वास्तव में है, वास्तव में आवश्यक है, विशेष रूप से विंडोज 7 के x64 संस्करण पर Very Bad Things happen जब कोई अपवाद हैंडलर नहीं है। हालांकि, जब आप डीबगर के साथ भागते हैं तो बैक-स्टॉप तब नहीं होता है, जो अनचाहे अपवादों को डीबग करना मुश्किल बनाता है।

तो जब आप डीबग करते हैं तो आपके पकड़ खंड चलाएगा। अनचाहे अपवाद बनाना डीबग करना बहुत मुश्किल है। जब आप डीबगर के बिना दौड़ते हैं तो आपका कैच क्लॉज रन नहीं होगा और जैसा कि आपने वर्णन किया है, आपका प्रोग्राम क्रैश हो जाएगा। अनचाहे अपवाद बनाना डीबग करना बहुत मुश्किल है।

तो इसे इस तरह से न करें। एप्लिकेशन.रुन() अनचाहे अपवादों से कैसे निपटता है एप्लिकेशन.SetUnhandledExceptionMode() विधि के साथ कॉन्फ़िगर किया गया है। आपको यह संस्करण बेहतर लगेगा:

[STAThread] 
    static void Main() { 
     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 
     if (!System.Diagnostics.Debugger.IsAttached) { 
      Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException); 
      AppDomain.CurrentDomain.UnhandledException += LogException; 
     } 
     Application.Run(new Form1()); 
    } 

    private static void LogException(object sender, UnhandledExceptionEventArgs e) { 
     string errordir = Path.Combine(Application.StartupPath, "errorlog"); 
     string errorlog = Path.Combine(errordir, DateTime.Now.ToString("yyyyMMdd_HHmmss_fff") + ".txt"); 
     if (!Directory.Exists(errordir)) 
      Directory.CreateDirectory(errordir); 
     File.WriteAllText(errorlog, e.ToString()); 
     AppDomain.CurrentDomain.UnhandledException -= LogException; 
     MessageBox.Show("Error details recorded in " + errorlog, "Unexpected error"); 
     Environment.Exit(1); 
    } 

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

आपको उपयोगकर्ता को अलर्ट देना चाहिए ताकि खिड़की किसी भी निशान के बिना गायब न हो। मैं संदेशबॉक्स की सिफारिश करने जा रहा था लेकिन ध्यान दिया कि this bug वर्तमान में विंडोज़ 10 पर फिर से वापस आ गया है।

+0

स्पष्टीकरण के लिए धन्यवाद, यह जवाब होना चाहिए। एक आखिरी सवाल, आप कह रहे हैं कि यह विंडोज 7 x64 के लिए विशेष रूप से खराब है, मैं विंडोज 10 x64 का उपयोग करता हूं। क्या इससे कोई फर्क पड़ता है? आपकी पोस्ट में, आपने कहा, "विंडोज 8 या बाद में अपडेट करें, उनके पास यह वाह 64 समस्या हल हो गई है।" - मुझे लगता है कि यह विंडोज 10 पर भी लागू होता है, क्या यह सही है? – Ian

+0

Win10 में यह समस्या नहीं है, यह Win7 के लिए अत्यधिक विशिष्ट है। –

+0

ठीक है, धन्यवाद। तब मुझे दिमाग में शांति मिलेगी ...;) मैं यह भी ध्यान देता हूं कि 'अपवाद 'के बाद' निपटान 'अभी भी * कहा जाता है। मैं 'SetUnhandledExceptionMode' को 'थ्रोएक्सप्शन' में कार्यान्वित करता हूं, मैंने इसे 'नई प्रणाली फेंकने के साथ परीक्षण किया। अपवाद()'। हैरानी की बात है कि कार्यक्रम * एक * के बजाय * दो * त्रुटि लॉग फ़ाइलों को उत्पन्न करता है। एक 'सिस्टम। अपवाद' है, और दूसरा 'निपटान' में 'अपवाद' है - और 'निपटान' में से एक * बाद में * बनाया गया है। ऐसा क्यों है? क्या यह वास्तव में उम्मीद है कि 'निपटान' अभी भी * घातक अपवाद के बाद * कहा जाता है? – Ian

2

ThreadException अपवाद प्रकार नहीं है (NullReferenceException)।

इस घटना को अपने Windows Forms अन्यथा बिना क्रिया अपवाद है जो Windows में होते हैं संभाल करने के लिए आवेदन फॉर्म्स धागे

इसका मतलब यह है कि यह मुख्य थ्रेड के अलावा अन्य धागे में अपवाद हैंडल अनुमति देता है: ऐसा नहीं है कि है। यह भी आदेश (अपवाद के प्रकार जैसे NullReference, IndexOutOfRange, आदि .. की परवाह किए बिना) अपने मुख्य थ्रेड में अपवाद को संभालने के लिए में AppDomain.CurrentDomain.UnhandledException:

तो, आप की सदस्यता के लिए की जरूरत है।

2

ठीक है, अंत में मैं Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException) रूप this post में VB.Net के लिए Hans Passant द्वारा exampled लागू।यहाँ मैं C# के लिए अपने खुद के कोड + त्रुटि लॉगिंग डाल:

static void Main() { 
    Application.EnableVisualStyles(); 
    Application.SetCompatibleTextRenderingDefault(false); 
    if (!System.Diagnostics.Debugger.IsAttached) { 
     Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException); 
     AppDomain.CurrentDomain.UnhandledException += LogUnhandledExceptions; 
    } 
    Application.Run(new T5ShortestTimeForm()); 
} 

private static void LogUnhandledExceptions(object sender, UnhandledExceptionEventArgs e) { 
    Exception ex = (Exception)e.ExceptionObject; 
    string errordir = Path.Combine(Application.StartupPath, "errorlog"); 
    string errorlog = Path.Combine(errordir, DateTime.Now.ToString("yyyyMMdd_HHmmss_fff") + ".txt"); 
    if (!Directory.Exists(errordir)) 
     Directory.CreateDirectory(errordir); 
    File.WriteAllText(errorlog, ex.ToString()); 
    Environment.Exit(System.Runtime.InteropServices.Marshal.GetHRForException(ex)); 
} 

इसके अलावा, यह भ्रम यहां के स्रोत की तरह लगता है वहाँ वास्तव में हैं कि दो प्रचारित Exceptions है होते हैं:

पहले एक किसी भी था

System.Exception: Exception of type 'System.Exception' was thrown. 
    at T5ShortestTime.T5ShortestTimeForm..ctor() in C:\Test.cs:line 45 
    at T5ShortestTime.Program.Main() in C:\Test.cs:line 19 
    at ... 

और दूसरा एक: आवेदन से ही अपवाद Form घटक है, जो एक और अपवाद पैदा की Dispose के दौरान होता है, और यह null संदर्भ अपवाद है:

System.NullReferenceException: Object reference not set to an instance of an object. 
    at T5ShortestTime.T5ShortestTimeForm.Dispose(Boolean disposing) 
    at System.ComponentModel.Component.Finalize() 

तो, जब मैं अपने अनुप्रयोग में अपवाद का परीक्षण, NullReferenceException पिछले आता है, Dispose में।

enter image description here

मैं केवल के बाद मैं ऊपर ThrowException को UnhandledExceptionMode सेट इस पर कब्जा करने का प्रबंधन।

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