विंडोज फॉर्म एप्लीकेशन में अपवाद हैंडलिंग के लिए सर्वश्रेष्ठ अभ्यास?


118

मैं वर्तमान में अपना पहला विंडोज़ फ़ॉर्म आवेदन लिखने की प्रक्रिया में हूँ। मैंने अब कुछ C # पुस्तकें पढ़ी हैं, इसलिए मुझे अपेक्षाकृत अच्छी समझ है कि C # भाषा को अपवादों से निपटने के लिए क्या सुविधाएँ हैं। वे सभी काफी सैद्धांतिक हैं, लेकिन जो मुझे अभी तक नहीं मिला है वह यह है कि बुनियादी अवधारणाओं को अपने आवेदन में एक अच्छे अपवाद-हैंडलिंग मॉडल में कैसे अनुवाद किया जाए।

क्या कोई इस विषय पर ज्ञान के मोती बाँटना पसंद करेगा? अपने द्वारा किए गए किसी भी सामान्य गलतियों को पोस्ट करें, और अपवादों को संभालने के बारे में कोई भी सामान्य सलाह, जो मेरे आवेदन को अधिक स्थिर और मजबूत बना दे।

वर्तमान में मैं जिन मुख्य चीजों को करने की कोशिश कर रहा हूं वे हैं:

  • मुझे एक अपवाद को फिर से कैसे फेंकना चाहिए?
  • क्या मुझे किसी तरह की केंद्रीय त्रुटि-हैंडलिंग तंत्र की कोशिश करनी चाहिए?
  • अपवादों को संभालना, जिन्हें पूर्व-खाली परीक्षण चीजों की तुलना में एक प्रदर्शन हिट हो सकता है जैसे कि क्या डिस्क पर एक फ़ाइल मौजूद है?
  • क्या सभी निष्पादन योग्य कोड को ट्राइ-कैच-अंततः ब्लॉकों में संलग्न किया जाना चाहिए?
  • क्या किसी भी समय एक खाली कैच ब्लॉक स्वीकार्य हो सकता है?

सभी सलाह कृतज्ञता प्राप्त!

जवाबों:


79

कुछ और बिट्स ...

आपके पास जगह में एक केंद्रीकृत अपवाद हैंडलिंग नीति होनी चाहिए। यह Main()एक कोशिश / पकड़ में रैपिंग जितना सरल हो सकता है, उपयोगकर्ता के लिए एक सुंदर त्रुटि संदेश के साथ तेजी से विफल हो रहा है। यह "अंतिम उपाय" अपवाद हैंडलर है।

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

कभी भी एक "निगलना" एक अपवाद नहीं है, सबसे अच्छी तरह से प्रलेखित मामलों को छोड़कर जब आप पूरी तरह से हैं, तो सकारात्मक रूप से सुनिश्चित करें कि फेंका जा रहा अपवाद जीवंत है। यह लगभग कभी नहीं होगा। (और अगर यह है, तो सुनिश्चित करें कि आप केवल विशिष्ट अपवाद वर्ग को निगल रहे हैं - कभी भी निगल न लें System.Exception।)

पुस्तकालयों का निर्माण करते समय (आपके ऐप द्वारा उपयोग किया जाता है), अपवादों को न निगलें, और अपवादों को भड़कने से डरो मत। जब तक आपके पास जोड़ने के लिए कुछ उपयोगी न हो, तब तक पुन: फेंक न दें। कभी भी (C # में) ऐसा न करें:

throw ex;

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

throw;

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

.NET में अपवाद हैंडलिंग विज्ञान की तुलना में अधिक कला है। यहां साझा करने के लिए हर किसी का पसंदीदा होगा। ये केवल कुछ युक्तियां हैं। मैंने दिन 1 से ही .NET का उपयोग किया है, ऐसी तकनीकें जिन्होंने मेरे बेकन को एक से अधिक मौकों पर बचाया है। आपकी माइलेज भिन्न हो सकती है।


1
यदि कोई अपवाद बबल देता है, तो किसी को फोन करने वाले को यह कैसे पता होना चाहिए कि क्या अपवाद इंगित करता है कि एक ऑपरेशन विफल हो गया है, लेकिन सिस्टम मौलिक रूप से ठीक है (जैसे एक उपयोगकर्ता ने एक भ्रष्ट दस्तावेज़ फ़ाइल खोलने की कोशिश की; फ़ाइल लोड नहीं होती है, लेकिन सब कुछ और ठीक होना चाहिए), या क्या यह इंगित करता है कि सीपीयू आग पर है और एक को जितनी जल्दी हो सके बाहर निकलने के लिए सिर चाहिए? ArgumentException जैसी कोई चीज़ या तो यह बता सकती है कि यह किन परिस्थितियों में फेंका गया है।
सुपरकैट

2
@supercat ApplicationExceptionउन विफलता मामलों के लिए विशिष्ट उपवर्ग लिखकर जो आवेदन को यथोचित रूप से अलग करने और संभालने में सक्षम होना चाहिए।
मैट एनराइट

@ माइट एन्योर: निश्चित रूप से किसी के अपने अपवादों को पकड़ना संभव है, लेकिन मैं किसी भी चीज से अनभिज्ञ हूं जो एक कन्वेंशन से मिलता-जुलता है, जिसके द्वारा अपवादों को फेंकने वाले संकेत देते हैं कि क्या वे बाहर किसी भी राज्य के भ्रष्टाचार को इंगित करते हैं कि विफलता से क्या निहित है। आदर्श रूप से, SuperDocument.CreateFromFile () की तरह एक विधि, या तो सफल होगी, एक CleanFailure अपवाद को फेंक देगी, या एक SomeReallyBadHappenedException को फेंक देगी। दुर्भाग्य से, जब तक कि कोई भी सब कुछ नहीं पकड़ता है जो अपने स्वयं के कैच ब्लॉक के भीतर एक अपवाद को फेंक सकता है, तो यह जानने का कोई तरीका नहीं है कि क्या एक InvalidOperationException ...
Supercat

@Matt Enright: ... को CleanFailureException या किसी SomeReallyBadHappenedException में लपेटा जाना चाहिए। और व्यक्तिगत कोशिश पकड़ने वाले ब्लॉकों में सब कुछ लपेटकर पहली जगह में अपवाद होने के पूरे उद्देश्य को पराजित किया जाएगा।
Supercat

2
मुझे लगता है कि यह एक खराब लाइब्रेरी डिज़ाइन है, जो एक गलत अपवाद प्रकार के साथ विफलता के तरीकों को छिपाने के लिए है। यदि आप वास्तव में क्या मतलब है IOException या एक InvalidDataException है, तो FileNotFoundException को न फेंकें, क्योंकि एप्लिकेशन को प्रत्येक मामले में अलग-अलग प्रतिक्रिया देने की आवश्यकता होती है। StackOverflowException या OutOfMemoryException जैसी चीज़ों को किसी एप्लिकेशन द्वारा यथोचित रूप से नियंत्रित नहीं किया जा सकता है, इसलिए बस उन्हें बबल दें, क्योंकि एक अच्छी तरह से व्यवहार किए गए एप्लिकेशन में वैसे भी केंद्रीकृत "अंतिम उपाय" हैंडलर होता है।
मैट एनराइट

63

यहाँ एक उत्कृष्ट कोड CodeProject लेख है । यहाँ कुछ हाइलाइट्स दिए गए हैं:

  • सबसे बुरे के लिए योजना *
  • इसकी जल्द जांच करें
  • बाहरी डेटा पर भरोसा न करें
  • केवल विश्वसनीय उपकरण हैं: वीडियो, माउस और कीबोर्ड।
  • लेखन विफल भी हो सकता है
  • कोड सुरक्षित रूप से
  • नया अपवाद न डालें ()
  • संदेश फ़ील्ड पर महत्वपूर्ण अपवाद जानकारी न रखें
  • प्रति धागे एक एकल पकड़ (अपवाद पूर्व) डालें
  • जेनेरिक अपवादों को प्रकाशित किया जाना चाहिए
  • लॉग अपवाद। TString (); केवल Exception.Message लॉग न करें!
  • प्रति धागा एक बार से अधिक (अपवाद) को न पकड़ें
  • अपवादों को कभी न निगलें
  • अंत में ब्लॉक में सफाई कोड लगाया जाना चाहिए
  • हर जगह "उपयोग" करें
  • त्रुटि स्थितियों पर विशेष मान वापस न करें
  • संसाधन की अनुपस्थिति को इंगित करने के लिए अपवादों का उपयोग न करें
  • एक विधि से जानकारी वापस करने के साधन के रूप में अपवाद हैंडलिंग का उपयोग न करें
  • त्रुटियों के लिए अपवादों का उपयोग करें जिन्हें अनदेखा नहीं किया जाना चाहिए
  • एक अपवाद को फिर से फेंकने पर स्टैक ट्रेस को साफ़ न करें
  • सिमेंटिक वैल्यू को जोड़े बिना अपवादों को बदलने से बचें
  • अपवादों को चिह्नित किया जाना चाहिए [सीरियल योग्य]
  • जब संदेह हो, तो जोर से मत करो, एक अपवाद फेंक दो
  • प्रत्येक अपवाद वर्ग में कम से कम तीन मूल निर्माता होने चाहिए
  • AppDomain.UnhandledException इवेंट का उपयोग करते समय सावधान रहें
  • पहिया को सुदृढ़ मत करो
  • असंरचित त्रुटि हैंडलिंग (VB.Net) का उपयोग न करें

3
क्या आप मुझे इस बात की ओर इशारा करना चाहते हैं? "संसाधन की अनुपस्थिति को इंगित करने के लिए अपवादों का उपयोग न करें" मुझे यकीन नहीं है कि मैं इसके पीछे का कारण समझता हूं। इसके अलावा सिर्फ एक टिप्पणी: यह उत्तर "क्यों" बिल्कुल नहीं समझाता है। मुझे पता है कि यह 5 साल पुराना है, लेकिन यह अभी भी मुझे थोड़ा
परेशान करता है

संदर्भित लेख का लिंक समाप्त हो गया है। कोड प्रोजेक्ट बताता है कि लेख यहां स्थानांतरित हो सकता है ।
डेविड आरआर

15

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

अनहैंडल्ड अपवाद डायलॉग को प्रदर्शित होने से रोकने के लिए और लॉगिंग और / या अपनी त्रुटि संवाद प्रदान करने के लिए ऐसे अपवादों को पकड़ने के लिए आप अपने मुख्य () विधि में Application.Run () को कॉल करने से पहले Application.ThreadException इवेंट में संलग्न कर सकते हैं।


इस सुझाव के लिए धन्यवाद, मैंने इसे बहुत देर से सीखा है, मैंने अभी इसे linqpad में सत्यापित किया है, उम्मीद के मुताबिक काम करता है, प्रतिनिधि है: void Form1_UIThreadException (ऑब्जेक्ट प्रेषक, ThreadExceptionEventArgs t) इस विषय के बारे में एक और अच्छी बात है richnewman.wordpress.com/2007/ 04/08 /… समग्र अखंडित अपवाद हैंडलिंग के लिए: AppDomain.UnhandledException घटना गैर-मुख्य-UI-थ्रेड से फेंके गए अपवादित अपवाद के लिए है।
झाउरुफ़ेई

14

यहां अब तक की गई सभी सलाह अच्छी और मूल्य देने लायक है।

एक बात जिस पर मैं विस्तार करना चाहूंगा, वह है आपका सवाल "क्या अपवादों को संभालना जो फेंक दिया जा सकता है, पूर्व-खाली परीक्षण चीजों की तुलना में एक प्रदर्शन हिट हो सकता है जैसे कि डिस्क पर कोई फ़ाइल मौजूद है?"

अंगूठे का भोला नियम "कोशिश / पकड़ ब्लॉक महंगे हैं।" यह वास्तव में सच नहीं है। कोशिश करना महंगा नहीं है। यह कैचिंग है, जहां सिस्टम को एक्सेप्शन ऑब्जेक्ट बनाना है और स्टैक ट्रेस के साथ लोड करना है, यह महंगा है। ऐसे कई मामले हैं जिनमें अपवाद है, ठीक है, असाधारण रूप से पर्याप्त है कि कोड को कोशिश / कैच ब्लॉक में लपेटना पूरी तरह से ठीक है।

उदाहरण के लिए, यदि आप किसी शब्दकोश को पॉप्युलेट कर रहे हैं, तो:

try
{
   dict.Add(key, value);
}
catch(KeyException)
{
}

अक्सर ऐसा करने से तेज होता है:

if (!dict.ContainsKey(key))
{
   dict.Add(key, value);
}

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

आपके द्वारा दिए गए उदाहरण में, मैं बिना सोचे-समझे कोशिश / पकड़ का उपयोग करूंगा। सबसे पहले, सिर्फ इसलिए कि फ़ाइल मौजूद है जब आप इसके लिए जाँच करते हैं इसका मतलब यह नहीं है कि जब आप इसे खोलते हैं तो यह मौजूद होने वाला है, इसलिए आपको वास्तव में वैसे भी अपवाद को संभालना चाहिए।

दूसरा, और मुझे और अधिक महत्वपूर्ण रूप से लगता है, जब तक कि आपकी) आपकी प्रक्रिया हजारों फाइलें नहीं खोल रही है और ख) ऐसी फाइल के ऑड्स को खोलने की कोशिश कर रहा है जो मौजूदा नहीं है, तुच्छ रूप से कम नहीं है, अपवाद बनाने का प्रदर्शन आपको कुछ नहीं है ' कभी नोटिस करने जा रहे हैं। सामान्यतया, जब आपका प्रोग्राम किसी फ़ाइल को खोलने का प्रयास कर रहा होता है, तो वह केवल एक फ़ाइल को खोलने का प्रयास करता है। यह एक ऐसा मामला है जहाँ सुरक्षित कोड लिखना लगभग निश्चित रूप से सबसे तेज़ संभव कोड लिखने से बेहतर है।


3
तानाशाह के मामले में, आप बस यह कर सकते हैं: dict[key] = valueजो उपवास के रूप में तेज होना चाहिए ..
nawfal

9

यहां कुछ दिशानिर्देश दिए गए हैं जिनका मैं पालन करता हूं

  1. फेल-फास्ट: यह एक अपवाद उत्पन्न करने वाली गाइडलाइन से अधिक है, जो आपके द्वारा किए जाने वाले प्रत्येक अनुमान और प्रत्येक पैरामीटर के लिए जो आप एक फंक्शन में प्राप्त कर रहे हैं, यह सुनिश्चित करने के लिए एक चेक करें कि आप सही डेटा के साथ शुरुआत कर रहे हैं और यह कि आप जो अनुमान लगा रहे हैं 'सही बना रहे हैं। विशिष्ट जांच में शामिल हैं, तर्क शून्य नहीं, अपेक्षित सीमा में तर्क आदि।

  2. जब रीथ्रोइंग स्टैक ट्रेस को संरक्षित करता है - यह केवल नए एक्सेप्शन () फेंकने के बजाय रीथ्रोइंग करते समय थ्रो का उपयोग करने के लिए अनुवाद करता है। वैकल्पिक रूप से यदि आपको लगता है कि आप अधिक जानकारी जोड़ सकते हैं तो मूल अपवाद को आंतरिक अपवाद के रूप में लपेटें। लेकिन अगर आप केवल लॉग करने के लिए अपवाद को पकड़ रहे हैं तो थ्रो का उपयोग जरूर करें;

  3. उन अपवादों को न पकड़ें जिन्हें आप संभाल नहीं सकते हैं, इसलिए OutOfMemoryException जैसी चीज़ों के बारे में चिंता न करें क्योंकि यदि वे होते हैं तो आप बहुत कुछ भी करने में सक्षम नहीं होंगे।

  4. वैश्विक अपवाद हैंडलर को हुक करें और जितना संभव हो उतना जानकारी लॉग करना सुनिश्चित करें। Winforms हुक के लिए दोनों अपडोमेन और थ्रेड को अनहेल्दी अपवाद ईवेंट्स।

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

  6. निश्चित रूप से ऐसे समय होते हैं जब खाली कैच ब्लॉक की आवश्यकता होती है, मुझे लगता है कि जो लोग कहते हैं अन्यथा उन कोडबेस पर काम नहीं किया है जो कई रिलीज पर विकसित हुए हैं। लेकिन उन्हें टिप्पणी की जानी चाहिए और यह सुनिश्चित करने के लिए समीक्षा की जानी चाहिए कि वे वास्तव में आवश्यक हैं। सबसे सामान्य उदाहरण डेवलपर्स है जो ParseInt () का उपयोग करने के बजाय स्ट्रिंग को पूर्णांक में बदलने के लिए कोशिश / पकड़ का उपयोग कर रहा है।

  7. यदि आप अपने कोड के कॉलर से अपेक्षा करते हैं कि वह त्रुटि स्थितियों को संभालने में सक्षम होगा, तो कस्टम अपवाद बनाएं जो यह बताता है कि गैर-बहिष्कृत स्थिति क्या है और संबंधित जानकारी प्रदान करें। अन्यथा केवल बिल्ट-इन अपवाद प्रकारों से जितना संभव हो सके चिपका दें।


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

Application.ThreadExceptionजब आप "थ्रेड अखंडित अपवाद" घटना को संदर्भित करते हैं, तो क्या आप इस घटना को संभालते हैं ?
जेफ बी

4

मुझे कुछ भी नहीं पकड़ने का दर्शन पसंद है, जिसे संभालने का इरादा नहीं है, जो कुछ भी मेरे विशेष संदर्भ में हैंडलिंग का मतलब है।

जब मैं कोड देखता हूं तो मुझे इससे नफरत है:

try
{
   // some stuff is done here
}
catch
{
}

मैंने इसे समय-समय पर देखा है और जब कोई व्यक्ति अपवादों को खाता है तो समस्याओं का पता लगाना काफी मुश्किल है। एक सहकर्मी मेरे पास यह था और यह मुद्दों की एक स्थिर धारा के लिए एक योगदानकर्ता होने के लिए समाप्त होता है।

अगर कुछ ऐसा है जिसे मेरे विशेष वर्ग को अपवाद के जवाब में करने की जरूरत है, तो मैं फिर से फेंक देता हूं, लेकिन समस्या को बुदबुदा कर बताने की जरूरत है कि यह विधि कहां है।

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


@Kiquenet क्षमा करें, मैं थोड़ा अस्पष्ट था। मेरा क्या मतलब था: इस तरह के खाली कैच मत करो, इसके बजाय डिस्पैचर के लिए एक हैंडलर जोड़ें। UnnhandledException , और कम से कम एक लॉग जोड़ें ताकि इसकी रोटी ब्रेडक्रंब के बिना न खाएं :) लेकिन जब तक आपको एक मूक घटक की आवश्यकता न हो, तब तक अलाउवे को अपवाद शामिल करना चाहिए। अपने डिजाइन में। उन्हें फेंक दें जब उन्हें फेंकने की आवश्यकता होती है, तो आप के लिए स्पष्ट अनुबंध करें Interfaces / API / किसी भी वर्ग।
लकीलीके

4

मैं अभी अपने रास्ते पर हूं लेकिन आपको अपवाद संचालन का उपयोग करने के लिए एक संक्षिप्त रन देगा। जब मैं लौटूंगा तो आपके अन्य बिंदुओं को संबोधित करने का प्रयास करूंगा :)

  1. सभी ज्ञात त्रुटि स्थितियों के लिए स्पष्ट रूप से जांचें *
  2. यदि आप सभी मामलों को संभालने में सक्षम थे तो कोड के आसपास एक कोशिश / पकड़ जोड़ें
  3. कोड के चारों ओर एक कोशिश / कैच जोड़ें यदि आप जिस .NET इंटरफ़ेस को कॉल कर रहे हैं वह एक अपवाद है
  4. कोड के चारों ओर एक कोशिश / पकड़ जोड़ें अगर यह आपके लिए एक जटिलता सीमा पार करता है
  5. यदि संन्यास की जाँच हो तो कोड के चारों ओर एक कोशिश / कैच जोड़ें: आप इस समस्या को दूर कर रहे हैं
  6. सामान्य नियम के रूप में, मैं रिटर्न कोड के प्रतिस्थापन के रूप में अपवादों का उपयोग नहीं करता हूं। यह .NET के लिए ठीक है, लेकिन मुझे नहीं। मेरे पास इस नियम के अपवाद (हेहे) हैं, हालांकि यह उस अनुप्रयोग की वास्तुकला पर निर्भर करता है जिस पर आप काम कर रहे हैं।

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

मैं एक के लिए भारी अपवाद आधारित आर्किटेक्चर से दूर चला जाता हूं। कोशिश / कैच में एक प्रदर्शन हिट नहीं होता है, जैसे कि अपवाद को फेंकने पर हिट आता है और कुछ को संभालने से पहले कोड को कॉल स्टैक के कई स्तरों तक चलना पड़ सकता है।


4

सुनहरा नियम जिसने छड़ी करने की कोशिश की है वह अपवाद को यथासंभव स्रोत के करीब संभाल सकता है।

यदि आपको एक अपवाद को पुन: फेंकना है, तो इसे जोड़ने का प्रयास करें, एक FileNotFoundException को फिर से फेंकने से बहुत मदद नहीं मिलती है, लेकिन एक कॉन्फ़िगरेशनफाइलNotFoundException को फेंकने से इसे कैप्चर किया जा सकता है और कहीं न कहीं चेन पर कार्रवाई की जा सकती है।

एक और नियम जिसका मैं पालन करने की कोशिश कर रहा हूं कि प्रोग्राम फ्लो के रूप में कोशिश / कैच का उपयोग नहीं करना है, इसलिए मैं फ़ाइलों / कनेक्शनों का सत्यापन करता हूं, यह सुनिश्चित करने के लिए कि वस्तुओं को शुरू किया गया है, उन्हें उपयोग करने से पहले ect ..। अपवादों के लिए कोशिश / पकड़ होनी चाहिए, जिन चीजों को आप नियंत्रित नहीं कर सकते हैं।

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


यह "सुनहरा नियम" सबसे अच्छा है।
इवान हार्पर

3

आप ThreadException इवेंट को ट्रैप कर सकते हैं।

  1. समाधान एक्सप्लोरर में एक विंडोज एप्लिकेशन परियोजना का चयन करें।

  2. उस पर डबल-क्लिक करके जनरेट किए गए Program.cs फ़ाइल को खोलें।

  3. कोड फ़ाइल के शीर्ष पर कोड की निम्नलिखित पंक्ति जोड़ें:

    using System.Threading;
  4. मुख्य () विधि में, विधि की पहली पंक्ति के रूप में निम्नलिखित जोड़ें:

    Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);
  5. निम्न को मुख्य () विधि से जोड़ें:

    static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
    {
        // Do logging or whatever here
        Application.Exit();
    }
  6. ईवेंट हैंडलर के भीतर अखंड अपवाद को संभालने के लिए कोड जोड़ें। कोई भी अपवाद जो अनुप्रयोग में कहीं और संभाला नहीं गया है, उपरोक्त कोड द्वारा संभाला गया है। आमतौर पर, इस कोड में त्रुटि दर्ज होनी चाहिए और उपयोगकर्ता को एक संदेश दिखाना चाहिए।

refrence: https://blogs.msmvps.com/deborahk/global-exception-handler-winforms/


@Kiquenet क्षमा करें, मैं
Omid-RH

2

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

अगर अपवाद को छोड़ दे तो भी ऐसा न करें। त्रुटियों को कभी ध्यान न दें।

उदाहरण:

void Main()
{
  try {
    DoStuff();
  }
  catch(Exception ex) {
    LogStuff(ex.ToString());
  }

void DoStuff() {
... Stuff ...
}

अगर DoStuff गलत हो जाता है, तो आप इसे किसी भी तरह से जमानत देना चाहेंगे। अपवाद मुख्य तक फेंक दिया जाएगा और आप पूर्व के स्टैक ट्रेस में घटनाओं की ट्रेन देखेंगे।


1

मुझे एक अपवाद को फिर से कैसे फेंकना चाहिए?

हर जगह, लेकिन अंत उपयोगकर्ता के तरीके ... जैसे बटन क्लिक हैंडलर

क्या मुझे किसी तरह की केंद्रीय त्रुटि-हैंडलिंग तंत्र की कोशिश करनी चाहिए?

मैं एक लॉग फ़ाइल लिखता हूं ... एक WinForm ऐप के लिए बहुत आसान है

अपवादों को संभालना, जिन्हें पूर्व-खाली परीक्षण चीजों की तुलना में एक प्रदर्शन हिट हो सकता है जैसे कि क्या डिस्क पर एक फ़ाइल मौजूद है?

मुझे इस पर यकीन नहीं है, लेकिन मेरा मानना ​​है कि अपवादों को कम करना एक अच्छा अभ्यास है ... मेरा मतलब है कि आप पूछ सकते हैं कि क्या कोई फ़ाइल मौजूद है और अगर यह FileNotFoundException नहीं है

क्या सभी निष्पादन योग्य कोड को ट्राइ-कैच-अंततः ब्लॉकों में संलग्न किया जाना चाहिए?

यीप

क्या किसी भी समय एक खाली कैच ब्लॉक स्वीकार्य हो सकता है?

हाँ, मान लें कि आप एक तिथि दिखाना चाहते हैं, लेकिन आपके पास कोई सुराग नहीं है कि उस तिथि को कैसे संग्रहीत किया गया था (dd / mm / yyyy, mm / dd / yyyy, आदि) आप इसे tp पार्स करने की कोशिश करते हैं लेकिन यदि यह विफल रहता है तो इसे जारी रखें .. , अगर यह आपके लिए अप्रासंगिक है ... मैं कहूंगा हाँ, वहाँ है


1

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

मैंने उन स्थानों पर खाली कैच-ब्लॉक्स का उपयोग किया है जहां उपयोगकर्ता कुछ ऐसा कर सकता है जो वास्तव में "गलत" नहीं है, लेकिन यह एक अपवाद को फेंक सकता है ... एक उदाहरण जो दिमाग में आता है अगर उपयोगकर्ता ग्रे प्लेसहोल्डर को डबल क्लिक करता है शीर्ष-बाईं ओर स्थित सेल, यह CellDoubleClick ईवेंट को आग देगा, लेकिन सेल एक पंक्ति से संबंधित नहीं है। उस मामले में, आप नहीं वास्तव में एक संदेश पोस्ट करने की आवश्यकता है लेकिन अगर आप इसे नहीं पकड़ते हैं तो यह उपयोगकर्ता को एक अनहेल्ड अपवाद त्रुटि फेंक देगा।


1

जब एक अपवाद को फिर से फेंकते हैं तो कुंजी शब्द इसे स्वयं द्वारा फेंक देता है। यह पकड़े गए अपवाद को फेंक देगा और अभी भी यह देखने के लिए स्टैक ट्रेस का उपयोग करने में सक्षम होगा कि यह कहां से आया है।

Try
{
int a = 10 / 0;
}
catch(exception e){
//error logging
throw;
}

ऐसा करने से स्टैक ट्रेस कैच स्टेटमेंट में समाप्त हो जाएगा। (इससे बचें)

catch(Exception e)
// logging
throw e;
}

क्या यह अभी भी .NET फ्रेमवर्क और .NET कोर के सबसे हाल के संस्करणों पर लागू होता है?
लकीलीकी

1

n मेरा अनुभव मैंने अपवादों को पकड़ने के लिए फिट देखा है जब मुझे पता है कि मैं उन्हें बनाने जा रहा हूं। ऐसे उदाहरणों के लिए जब मैं एक वेब अनुप्रयोग में हूं और एक प्रतिक्रिया कर रहा हूं। अप्रत्यक्ष, मुझे पता है कि मुझे एक System.ThreadAbortException मिल जाएगा। चूंकि यह जानबूझकर है, मेरे पास विशिष्ट प्रकार के लिए एक पकड़ है और बस इसे निगल लें।

try
{
/*Doing stuff that may cause an exception*/
Response.Redirect("http:\\www.somewhereelse.com");
}
catch (ThreadAbortException tex){/*Ignore*/}
catch (Exception ex){/*HandleException*/}

1

मैं इस नियम से गहराई से सहमत हूँ:

  • त्रुटियों को कभी ध्यान न दें।

कारण यह है कि:

  • जब आप पहली बार कोड लिखते हैं, तो सबसे अधिक संभावना है कि आपको 3-पार्टी कोड, .NET FCL लिरीरी या आपके सह-कार्यकर्ताओं के नवीनतम योगदानों की पूरी जानकारी नहीं होगी। वास्तव में आप कोड लिखने से तब तक इंकार नहीं कर सकते जब तक आप हर अपवाद को अच्छी तरह से नहीं जानते। इसलिए
  • मुझे लगातार पता चलता है कि मैं कोशिश / कैच (अपवाद पूर्व) का उपयोग करता हूं क्योंकि मैं खुद को अज्ञात चीजों से बचाना चाहता हूं, और, जैसा कि आपने देखा, मैं अपवाद को पकड़ता हूं, न कि अधिक विशिष्ट जैसे कि आउटऑफमैरीएक्स अपवाद इत्यादि और, मैं हमेशा अपवाद बनाता हूं। ForceAssert.AlwaysAssert (गलत, ex.ToString ()) द्वारा मुझे (या QA) को पॉप अप किया जा रहा है;

ForceAssert.AlwaysAssert मेरा व्यक्तिगत तरीका है Trace.Assert सिर्फ इस बात की परवाह किए बिना कि DEBUG / TRACE मैक्रो को परिभाषित किया गया है।

हो सकता है कि विकास चक्र: मैंने बदसूरत मुखर संवाद पर ध्यान दिया या किसी और ने मुझे इसके बारे में शिकायत की, तो मैं कोड पर वापस आता हूं और अपवाद को उठाने का कारण जानने और यह तय करने का तरीका तय करता हूं।

इस तरह से मैं लिख सकता है मेरी कम समय में कोड और मुझे अज्ञात डोमेन से संरक्षित किया है, लेकिन हमेशा देखा जा रहा है, तो असामान्य बातें, क्या हुआ इस तरह से प्रणाली सुरक्षित और अधिक सुरक्षा मिल द्वारा।

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

WinForms कोड के लिए, एक सुनहरा नियम जिसका मैं हमेशा पालन करता हूं:

  • हमेशा अपने ईवेंट हैंडलर कोड को आज़माएं (कैच करें)

यह आपके UI को हमेशा प्रयोग करने योग्य होने से बचाएगा।

प्रदर्शन हिट के लिए, प्रदर्शन जुर्माना केवल तब होता है जब कोड पहुंचता है, वास्तविक अपवाद के बिना कोशिश कोड को निष्पादित करने से कोई महत्वपूर्ण प्रभाव नहीं पड़ता है।

अपवाद थोड़ा मौका के साथ होना चाहिए, अन्यथा यह अपवाद नहीं है।


-1

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

इसलिए आपको कभी भी गर्भ धारण करना चाहिए और सोचें कि आपके ऐप में कोई बग नहीं है, इसकी गारंटी नहीं है। और यह उपयुक्त कोड के बारे में कुछ कोशिश पकड़ने वाले ब्लॉकों को लपेटने और त्रुटि संदेश दिखाने / त्रुटि लॉग करने का एक बहुत छोटा प्रयास है।

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


क्या आप एक शेख़ी की तरह कम जवाब लिखने की कोशिश कर सकते हैं और इसके बजाय अधिक विशिष्ट होने की कोशिश कर सकते हैं और अपनी बात साबित करने की कोशिश कर सकते हैं? हाउ टू आंसर पर भी एक नजर ।
लकीलकी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.