2009-05-18 14 views
17

क्या कोई मुझे बता सकता है कि किसी भी अनचाहे अपवादों को पकड़ने के लिए मुख्य() विधि में प्रयास करने के लिए अनुचित क्यों माना जाता है?मुख्य() खराब क्यों प्रयास करें?

[STAThread] 
static void Main() 
{ 
    try 
    { 
     Application.Run(new Form1()); 
    } 
    catch (Exception e) 
    { 
     MessageBox.Show("General error: " + e.ToString()); 
    } 
} 

मुझे समझ है कि यह बुरा अभ्यास है, लेकिन यह सुनिश्चित नहीं है कि क्यों।

+2

आप अंतिम उपयोगकर्ता को इसके मुकाबले कुछ और जानकारीपूर्ण दिखाना चाहते हैं, और समर्थन उद्देश्यों के लिए अपवाद विवरण लॉग इन करना चाहते हैं, लेकिन अन्यथा मैं अनुचित के बजाय इसे सर्वोत्तम अभ्यास के रूप में अनुशंसा करता हूं! –

+1

वास्तव में अच्छा सवाल है। मुझे लगता है कि यहां जवाब थोड़ा "सूक्ष्म" है। बस इस दृष्टिकोण को बुलाओ "बुरी आदत" यह न्याय नहीं करता है। – Noldorin

उत्तर

28

मुझे नहीं लगता कि आवश्यक खराब अभ्यास है। कुछ चेतावनियां लेकिन इसके ...

मेरा मानना ​​है कि जो कोई भी इस "बुरा व्यवहार" कहा जाता है की बात यह विचार है कि आप वे कहाँ पाए जाते हैं के अपवाद निकटतम पकड़ने जाना चाहिए को मजबूत (यानी के रूप में उच्च अप कॉल यथासंभव ढेर/एप्राइपिएट)। एक कंबल अपवाद हैंडलर आमतौर पर एक अच्छा विचार नहीं है क्योंकि यह आपके लिए उपलब्ध नियंत्रण प्रवाह को काफी कम करता है। मोटे अनाज वाले अपवाद हैंडलिंग काफी महत्वपूर्ण प्रोग्राम स्थिरता के लिए एक उचित समाधान है। दुर्भाग्यवश, कई शुरुआती डेवलपर्स सोचते हैं कि यह है, और इस कंबल के प्रयास के रूप में इस तरह के दृष्टिकोण लेते हैं।

, इस कह अगर आप अपवाद अपने कार्यक्रम के बाकी हिस्सों में ठीक से निपटने (एक सुक्ष्म और कार्य-विशेष तरीके से) का उपयोग किया है, और त्रुटियों तदनुसार वहाँ (एक सामान्य त्रुटि बॉक्स प्रदर्शित संभाला बल्कि Juist से), फिरMain विधि में सभी अपवादों के लिए सामान्य प्रयास-पकड़ संभवतः एक उपयोगी बात है। यहां ध्यान देने योग्य एक बिंदु यह है कि यदि आप पुनरुत्पादित इस Main में पकड़े गए बग प्राप्त कर रहे हैं, तो आपके पास या तो आपके स्थानीय अपवाद हैंडलिंग के साथ कोई बग या कुछ गलत है।

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

+1

+1 वास्तव में खराब व्यवहार होने की तुलना में इसे "खराब अभ्यास" कहने का एक अलग कारण है। –

+1

मैं इस पर नोल्डोरिन से सहमत हूं। यदि आपके अपवाद के लिए आपके पास ठीक से निपटने वाले हैंडलिंग हैं, तो अपवाद जो इसे यहां बनाते हैं, वे या तो बग हैं, या वे पुनर्प्राप्त करने योग्य नहीं हैं (कभी-कभी जब कुछ बुरा होता है, तो आप इसके बारे में कुछ भी नहीं कर सकते हैं)। आप कुछ सामान्य जानकारी लॉग करने और उपयोगकर्ता को एक संदेश प्रदर्शित करने के लिए इस सामान्य अपवाद हैंडलर का उपयोग करेंगे (नोट: कोई गारंटी नहीं है कि आप एक गंभीर अपवाद के साथ लॉग इन कर सकते हैं - आप स्मृति से बाहर हो सकते हैं, या हो सकता है कि आपने डिस्क, आदि) – JMarsch

+0

@JMarsch: हाँ, बिल्कुल। कुछ गंभीर त्रुटियों को भी इससे पकड़ा नहीं जाएगा, हालांकि यह उन बगों के लिए असफलता के रूप में उपयोगी है जो परीक्षण के दौरान पकड़े नहीं जाते हैं (आदर्श रूप से रिपोर्ट किया जाना चाहिए) या केवल दुर्लभ दुर्लभ अवसरों के लिए। – Noldorin

1

आपको पकड़ने का सब अप मिला है जो सब कुछ फंस जाएगा। तो अगर आपके पास कोड में कोई अनचाहे अपवाद है तो आप उन्हें कभी नहीं देख पाएंगे।

सकारात्मक तरफ, आपका आवेदन कभी दुर्घटनाग्रस्त नहीं होगा!

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

+1

कैच-सब कुछ अपवाद के साथ कुछ उपयोगी नहीं कर सका, उदा। इसे लॉग करें, एक त्रुटि संवाद दिखाएं, अलार्म बढ़ाएं, आदि फिर प्रोग्राम शानदार ढंग से बाहर निकल सकता है। यह – Glen

+0

को तोड़ने से बेहतर लगता है इसलिए मेरी आखिरी वाक्य। – ChrisF

7

मुझे नहीं लगता कि यह कैसे बुरा व्यवहार है।

आपके प्रोग्राम को एक अनचाहे अपवाद त्रुटि के साथ क्रैश करने देना आपके अंतिम उपयोगकर्ताओं में कोई विश्वास नहीं पैदा करेगा।

शायद कोई और काउंटर व्यू प्रदान कर सकता है।

अद्यतन: स्पष्ट रूप से आपको अपवाद के साथ कुछ उपयोगी करने की आवश्यकता होगी।

  1. लॉग इन करें यह
  2. उपयोगकर्ता एक संवाद करते हुए कहा क्यों आवेदन है कि आपके आवेदन के संदर्भ में समझ में आता है और कुछ
  3. कुछ (सादा पाठ, एक स्टैकट्रेस नहीं में) से बाहर निकल रहा है दिखाते हैं।
+0

एक नई गलती है कि नए डेवलपर्स सभी अपवादों को पकड़ना है। यह आमतौर पर डूब जाता है क्योंकि इसमें बग मास्क करने की क्षमता होती है जिसे अन्यथा संबोधित किया जा सकता है।यदि आप अपवाद हैंडलर में त्रुटि से पुनर्प्राप्त नहीं हो सकते हैं, तो एप्लिकेशन क्रैश होने देना बेहतर हो सकता है। अंत उपयोगकर्ताओं द्वारा इस प्रकार की त्रुटियों की अधिक संभावना होने की संभावना है। अधिक जानकारी के लिए इस लिंक को पढ़ें: http://blogs.msdn.com/fxcop/archive/2006/06/14/631923.aspx – senfo

+1

मैं आंशिक रूप से सहमत हूं कि आपके कोड में सभी अपवाद खराब हैं। अपने मुख्य में अनचाहे अपवादों को पकड़ना और बाहर निकलने से पहले उनके साथ कुछ करना बुरा नहीं माना जाना चाहिए। यह सब कुछ करने की बात है कि आप क्या करने की कोशिश कर रहे हैं। आपके द्वारा लिंक किया गया लेख आम तौर पर सही है, लेकिन आपको ध्यान रखना चाहिए कि यह इस प्रश्न में उठाए गए विशिष्ट मामले से निपटता नहीं है, जो मुख्य में अपवाद को पकड़ रहा है। – Glen

5

मुझे लगता है कि में और स्वयं का एक बुरा व्यवहार है नहीं लगता। मुझे लगता है कि खराब अभ्यास होगा यदि वह आपके आवेदन में केवल कोशिश/पकड़ ब्लॉक था।

3

मुझे यकीन नहीं है कि मुझे यह एक बुरा अभ्यास लगता है। आप जो करना चाहते हैं, यह सुनिश्चित कर लें कि प्रोग्राम की अपवाद और वर्तमान स्थिति जब डेवलपर के हाथों में दुर्घटनाग्रस्त हो जाती है, तो तिथि, समय और उस उपयोगकर्ता के साथ काम करने वाले उपयोगकर्ता के साथ अधिमानतः लॉग इन किया जाता है। मूल रूप से - क्या आप वाकई अपनी टीम सभी जानकारी वे समस्या डिबग करने के लिए, उपयोगकर्ता दुर्घटना के बारे में उनसे चला जाता है या नहीं, की परवाह किए बिना की जरूरत है कि बनाना चाहते हैं। याद रखें कि अगर वे दुर्घटनाग्रस्त हो जाते हैं तो वास्तव में, बहुत से उपयोगकर्ता समर्थन से संपर्क नहीं करेंगे।

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

11

ठीक है, यह विधि केवल आपके मुख्य धागे में फेंकने वाले अपवादों को पकड़ लेगी। यदि आप Application.ThreadException और AppDomian.UnhandledException ईवेंट दोनों का उपयोग करते हैं तो आप सभी अपवादों को पकड़ने और लॉग इन करने में सक्षम होंगे।

+1

एप्लिकेशन। थ्रेडएक्सप्शन केवल जीयूआई थ्रेड पर अपवाद पकड़ता है। –

+1

हाँ, मुझे अभी एहसास हुआ कि मेरा जवाब अपडेट किया गया है। धन्यवाद। WER संवाद के लिए –

1

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

कहा जा रहा है, मुझे लगता है कि यह रिलीज समय पर एक अच्छा अभ्यास है। इसके अलावा, मैं AppDomain.UnhandledException और Application.ThreadException ईवेंट पर भी सुनना चाहता हूं। यह आपको और भी अपवादों को फंसाने देगा (जैसे कि कुछ सिस्टम अपवाद जो उपरोक्त आपके "वैश्विक" हैंडलर में नहीं पकड़े जाएंगे)।

आप त्रुटियों लॉग इन करें और एक अच्छा, स्वच्छ संदेश के साथ उपयोगकर्ता प्रदान करने के लिए अनुमति देता है।

0

मैं यह नहीं कह रहा हूँ यह बुरा व्यवहार, केवल एक चीज मैं हालांकि विभिन्न करना होगा का उपयोग करें कि के लिए घटना में बनाया गया है है:

 Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException); 

     static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e) 
     { 
      MessageBox.Show(e.Exception.Message); //or do whatever... 
     } 
1

इस के लिए यह परिवर्तन और यह ठीक है

catch(Exception ex) 
{ 
    YourLoggingSystem.LogException(ex); 
} 

बेशक, इस लाइन को कभी भी हिट नहीं किया जाना चाहिए क्योंकि आपके पास कोड के सभी चीजों को अधिक संदर्भ के साथ अन्य अपवाद हैंडलर होंगे।

1

उच्च-स्तरीय अपवाद हैंडलिंग बहुत जरूरी है, लेकिन मैं का उपयोग कर की सलाह देते हैं:

Application.ThreadException += new ThreadExceptionEventHandler(YourExceptionHandlingMethod); 

हालांकि, यह केवल जीयूआई धागा (ज्यादा अपने try..catch ब्लॉक की तरह) पर अपवाद पकड़ेगा - आप उन सभी नए थ्रेड के लिए समान कोड का उपयोग करना चाहिए जो आप उनसे अप्रत्याशित अपवादों को संभालने के लिए शुरू करते हैं।

इसके बारे में अधिक जानकारी here

0

मुझे लगता है कि यह आपके मुख्य() में प्रयास करने का प्रयास करने का सबसे अच्छा अभ्यास है।

हालांकि, मैं (अपने कोड में कुछ संशोधन करने हैं पकड़ने के लिए अपवाद यह लॉग इन करें, और उसके बाद संदेश बॉक्स:।

[STAThread] 
static void Main() 
{ 
    try 
    { 
     Application.Run(new Form1()); 
    } 
    catch (Exception ex) 
    { 
     EventLog log; 
     log = new EventLog("MyApp", Environment.MachineName, "Application"); 

     // write to the event log 
     log.WriteEntry(ex.message, Error); 
     MessageBox.Show("General error");  
    } 
} 
5

कोई अपवाद जो Main() जाता संभावना घातक है

हैं यह कुछ आसान था, इसे ऊपर से संभाला जाना चाहिए था। अगर यह आपके नियंत्रण से परे कुछ था, जैसे OutOfMemoryException, तो प्रोग्राम क्रैश होना चाहिए।

विंडोज आवेदक आयन जो दुर्घटना में ऐसा करने का एक मानक तरीका है, वे Windows Error Reporting संवाद को ट्रिगर करते हैं। (आपने इसे पहले देखा होगा)। ऐसा होने पर आप क्रैश डेटा प्राप्त करने के लिए साइन अप कर सकते हैं।

+0

+1 –

5

पुरातनता में, सी ++ में एक कोशिश/पकड़ रखने के कारण काफी भारी प्रदर्शन जुर्माना हुआ, और मुख्य रूप से एक को रखने का मतलब सब कुछ के लिए अतिरिक्त स्टैक जानकारी संग्रहीत करना होगा, जो प्रदर्शन के लिए फिर से खराब था।

अब कंप्यूटर तेज़ हैं, प्रोग्रामर कम प्रदर्शन के लिए आदी हैं, और रनटाइम्स बेहतर बनाए गए हैं, इसलिए अब यह वास्तव में बुरा नहीं है (लेकिन फिर भी आप इसके लिए थोड़ा और भुगतान कर सकते हैं, वर्षों में इसका प्रभाव बेंचमार्क नहीं किया है)। तो यह पुरानी लोककथा है जो अनाज के खिलाफ पुनरावृत्ति की तरह है (कंपाइलर्स वास्तव में आजकल आपके लिए पुनरावृत्ति को ठीक करते हैं)। सी # में यह बिल्कुल ठीक है, लेकिन यह 10 साल पहले किसी के लिए iffy देखेंगे।

0

मुझे लगता है कि यह निराश है क्योंकि अपवाद केवल एक बार पकड़े जाते हैं और पृष्ठभूमि थ्रेड की तरह कई चीजें हो सकती हैं, जिन्हें यह पता होना चाहिए कि कोई प्रक्रिया फेंकता है या नहीं।

यह एक WinForms अनुप्रयोग है? Forms.Application.Run जब भी एक धागा एक अनचाहे अपवाद फेंकता है तो घटनाओं को बढ़ाता है। एमएसडीएन दस्तावेज़ इसे समझाने की कोशिश करते हैं, लेकिन वे जो हैंडलर दिखाते हैं वे काम नहीं करते हैं! WinForms यूई साइट से updated example पढ़ें।

0

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

जितनी जल्दी संभव हो बाहर हो रही है सबसे अच्छा है, उदा बाहर निकलने के (1)। थोड़ा जोखिम भरा हालांकि लॉग और बाहर निकलना अच्छा है।

मुझे विश्वास नहीं है? Mitre Common Weakness Enumeration (CWE) agrees। इस तरह से advice against catching NULL pointer dereferencing निकटता से संबंधित है।

0

मैं एक लंबी व्याख्या में जा सकता हूं, लेकिन आप FxCop team blog response पढ़ने से बेहतर हैं।

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