2009-02-02 12 views
30

एक सी # एप्लिकेशन लिखते समय जिसका # 1 प्राथमिकता को कभी भी क्रैश नहीं करती है, मुझे कितनी बार कोशिश-पकड़ ब्लॉक का उपयोग करना चाहिए?सी # में कोशिश करने और पकड़ने के लिए मुझे कितनी बार उपयोग करना चाहिए?

क्या मैं कोशिश-पकड़ ब्लॉक में किसी विधि में सभी कथनों को समाहित कर सकता हूं?

public void SomeMethod() 
{ 
    try 
    { 
     // entire contents of the function 
     // library calls 
     // function calls 
     // variable initialization .. etc 
    } 
    catch (Exception e) 
    { 
     // recover 
    } 
} 

कोशिश-पकड़ ब्लॉक में सबकुछ लपेटने के लिए डाउनसाइड्स क्या हैं?

उत्तर

30

एकमात्र नीचे की ओर है जब एक अपवाद वास्तव में फेंक दिया जाता है। अपवाद होने पर, कोड को लपेटने के लिए कोई ओवरहेड नहीं है।

इसके अलावा, आप नियंत्रण प्रवाह के लिए प्रयास/पकड़ का उपयोग नहीं करना चाहते हैं। इस पर विचार करें (खराब कोड):

try { 

    FileStream fs = File.Open("somefile.txt", FileMode.Open); 

} catch (Exception ex) { 
    MessageBox.Show("The file does not exist. Please select another file"); 
} 

आपको फ़ाइल.इक्सिस्ट जैसी कुछ चीज़ों से अधिक प्रदर्शन मिलेगा। जैसे:

if(!File.Exists("somefile.txt")) 
    MessageBox.Show("The file does not exist.") 

संपादित करें: MSDN direct quote पाया:

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

+2

ठीक है, * न्यूनतम * ओवरहेड है। कुछ, लेकिन बहुत बहुत छोटे। –

+1

बुरी बात यह है कि जेआईटी कंपाइलर अपवाद हैंडलिंग संरचनाओं में इनलाइन कार्यों को रेखांकित नहीं कर सकता है –

+17

फ़ाइल के लिए जब आप इसे जांचते हैं और इसे खोलने का प्रयास करते हैं तो मौजूदा के लिए मौजूदा बंद करना संभव है। आपको यह सुनिश्चित करने के लिए प्रयास करें कि आप क्रैश न करें। –

1

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

+0

+1 पकड़ने के लिए नकारात्मकता को समझाने के लिए +1 (अपवाद ई)। – jason

+1

जब तक आप लॉगिंग और इसे फिर से फेंकने की तरह कुछ नहीं कर रहे हैं। –

8

दरअसल, लॉगिंग उद्देश्यों को छोड़कर मैं बहुत ही कम पकड़ ब्लॉक का उपयोग करता हूं। finally मेरे लिए बहुत आम है। अधिकांश बार, lock या using वह सब कुछ करें जो मैं उपयोगी रूप से कर सकता हूं (और वास्तव में, यह finally भी है)।

एरिक लिपर्ट में blog entry on exceptions है जो उपयोगी हो सकता है।

+1

(या निश्चित रूप से शीर्ष स्तर के यूआई हैंडलर के लिए) –

1

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

वेब ऐप्लिकेशन के लिए, वहाँ Global.asax एक सांत्वना कार्यक्रम के लिए है, के लिए, बस, आज़माएं/कैच में अपने मुख्य() लपेट सेवाओं के लिए, वहाँ AppDomain.CurrentDomain.UnhandledException, आदि

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

-1

आपको किसी भी समय कोड का एक टुकड़ा अपवाद फेंकने का उपयोग करना चाहिए।

आपको सावधान रहना होगा, सामान्य अपवादों को पकड़ना कभी अच्छा विचार नहीं है। आपको यह तय करना होगा कि आप कौन सी परत उन्हें संभालना चाहते हैं।

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

इस तरह आप मामले के आधार पर किसी मामले पर प्रत्येक अपवाद से निपट सकते हैं। एक सामान्य अपवाद जिसे आप नहीं जानना चाहते हैं कि क्या करना है।

+2

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

4

आम तौर पर आईएमओ एक छोटे से हिस्सों को रखना बेहतर होता है जो आपके नियंत्रण से बाहर हैं। यदि आप कहते हैं:

try 
{ 
    //anything that could possibly go wrong 
    //This kind of thing is only good for Logging IMO and could be done in 
    //Global.asax 
} 

कैसे आप संभवतः यह जान सके कि क्या अपनी पकड़ विधि में क्या करना है यह कुछ भी हो सकता कारण ...

इसकी काफी बेहतर जाना:

try 
{ 
    //divide user imputs 
} 
catch(DivideByZeroException) 
{ 
    // tell user bad inputs ect.... 
} 
catch (Exception e) 
{ 
    //If you choose to throw the exception you should 
    //*********************** 
    throw; 
    //VS 
    throw ex; //Throw ex will restart the stack trace 
    // recover 
} 
finally 
{ 
    //Clean up resources and continue 
} 

किस अंत में हमेशा

+1

अपवाद को पकड़ने के लिए भी बेहतर नहीं है और यह देखने के लिए पहले से जांचें कि यह मौजूद है या नहीं – jlembke

3

चलाया जाता है इस सवाल के लिए महत्वपूर्ण निम्न पंक्ति है:

// recover 

पुनर्प्राप्त करने में सक्षम होने के लिए, आपको पता होना चाहिए कि कैसे और कैसे ठीक किया जाए। और ऐसा लगता है कि इसे पुनर्प्राप्त करना संभव है, जो अक्सर नहीं होता है।

आपको अपवाद को निगलने के लिएके catch भाग का उपयोग केवल अपवाद को निगलने के लिए करना चाहिए, जब आप जानते हैं कि इससे कैसे पुनर्प्राप्त किया जाए, और जब आप सुनिश्चित हों कि आप एप्लिकेशन को छोड़ दिए बिना ऐसा कर सकते हैं एक असंगत या अमान्य स्थिति।

यदि आप अपने आवेदन में सभी विधि कॉल में सभी संभावित अपवादों के लिए ऐसा कर सकते हैं तो आगे बढ़ें, अन्यथा आपको अपनी # 1 प्राथमिकता को फिर से सोचने की आवश्यकता हो सकती है (कभी-कभी विफल होने की गति एक बेहतर विकल्प है जो रखने की कोशिश करने से बेहतर विकल्प है कुछ गलत हो गया है, और बाद में दुर्घटना डीबग करने के लिए बहुत कठिन है) आवेदन जिंदा है।

0

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

इसके अलावा, बेजोड़ अपवादों के खिलाफ सुरक्षा के लिए, हम एक UnhandledExceptionEventHandler को AppDomain.CurrentDomain से संलग्न करते हैं।

+1

मैंने इसे कम मत किया है, लेकिन आपका कथन "आपको यह सुनिश्चित करना होगा कि कोड की प्रत्येक पंक्ति या तो कोशिश में संलग्न है- पकड़ो ब्लॉक ... "गलत पैर पर शुरू होता है। यह बयान का दूसरा भाग है कि आपको यह सुनिश्चित करना है कि हमेशा एक अपस्ट्रीम अपवाद हैंडलर होता है। – jdigital

+0

यह एक खराब डिजाइन की तरह लगता है। मैंने जो कुछ भी पढ़ा है, उससे आपको पर्यावरण को संभालने के लिए प्रयास-कैच का उपयोग करना चाहिए, नेटवर्क (या सर्वर) संसाधनों पर निर्भर स्थितियां, या आपके नियंत्रण से बाहर हैं। इस प्रकार मैं नीचे वोट दूंगा। – ConfusedDeer

2

यदि आप इसे अर्थपूर्ण तरीके से संभाल सकते हैं तो आपको केवल इसे फिर से हटाए बिना अपवाद को पकड़ना और रोकना चाहिए। अन्यथा यह एक त्रुटि है और इसे प्रचार करना चाहिए।

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

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

23

यह एक बड़ा विषय है। अपवाद संचालन सर्वोत्तम प्रथाओं के कुछ उत्कृष्ट चर्चा के लिए here शुरू करें और एक धार्मिक युद्ध के लिए तैयार रहना ...

Code Analysis Team Blog

Martin Fowler - Fail Fast

MSDN on Exception Handling

Checked vs Unchecked Exceptions

मेरा अपना विचार है कि है अधिकांश भाग के लिए आप "कोशिश करें/अंततः" बहुत उपयोग करते हैं, लेकिन "पकड़" बहुत कम करते हैं। समस्या यह है कि यदि आप गलत उदाहरणों में अपवादों को पकड़ने और संभालने का प्रयास करते हैं, तो आप अनजाने में अपने आवेदन को खराब स्थिति में डाल सकते हैं। एक नियम के रूप में, यह जानने के लिए dev और test का उपयोग करें कि आपको वास्तव में अपवाद को संभालने की आवश्यकता है। वे स्थान होंगे जहां आप जांच नहीं सकते हैं। यानी आपको वास्तव में nulreference या filenotfound को संभालने की आवश्यकता नहीं है क्योंकि आप सक्रिय रूप से उन लोगों की जांच कर सकते हैं। केवल अपवाद जो आप जानते हैं, हो सकता है, लेकिन आप इसके बारे में कुछ भी नहीं कर सकते हैं। इसके अलावा, अपने डेटा के राज्य के लिए, इसे दुर्घटनाग्रस्त होने दें।

यदि आप अपवादों को निगल रहे हैं, तो आम तौर पर इसका मतलब है कि आप अपने प्रोग्राम को समझ नहीं सकते हैं या आपको अपवाद क्यों मिल रहा है। सी # में System.Exception बढ़ रहा है कोड का पोस्टर बच्चा गंध ...

+2

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

+0

यदि "# 1 प्राथमिकता कभी दुर्घटनाग्रस्त नहीं है" तो यह सिद्धांत में अच्छा है लेकिन यह आवश्यकताओं को पूरा नहीं करता है। मुझे यकीन है कि आप आवश्यकताओं के बारे में बहस करना चाहते हैं लेकिन मुझे संदेह है कि ओपी के पास यह विकल्प नहीं है (यदि उसने किया, तो वह पहले से ही अपने ग्राहक को यह समझाया होगा ;-) – jdigital

+0

@jdigital - सहमत है। यह एक अच्छी बात है। उनका प्रश्न – jlembke

-3

कोशिश पकड़:

try{ 

} 
catch (NullReferenceException en) 
{ 

} 
+3

-1: इसके बजाय 'NullReferenceException' को पकड़ें - _fix_ इसके बजाय। –

-1
public void functionName 
{ 
    try 
    { 
    //your codes 
    //sometimes 'return' shows exceptions 
    } 
    catch(Exception e) 
    { 
    messagebox.show(e.Tostring()); //to know what is the exception 
    } 
    finally 
    { 
    } 
} 
1

मैं आम तौर पर try catch ब्लॉकों से बचने की कोशिश। मैं उपयोगकर्ता को आवेदन के नियमों का पालन करने के लिए मजबूर करने के लिए लूप का उपयोग करना पसंद करता हूं। उदाहरण के लिए, यदि कोई उपयोगकर्ता केवल एक पूर्णांक है कि के बराबर या उससे किसी पूर्णांक x कम है में प्रवेश करना चाहिए मैं का उपयोग करेंगे:

if (input > x) 
{ 
    Console.WriteLine("Invalid input. Please enter a number that is equal to or less than x."); 
{...} 
} 
बजाय

का उपयोग कर:

catch (IndexOutOfRangeException) 
{ 
     //error message here 
} 

अपने स्वयं के व्यक्तिगत अनुभव रहा से लिखना आसान लगता है क्योंकि आप कोशिश ब्लॉक (कोडिंग कोड) में कोड encapsulating से बच सकते हैं।

बेशक, हमेशा ऐसे समय होंगे जहां कोशिश पकड़ने का उपयोग करना अपरिहार्य है - मैं बस जहां संभव हो वहां काम करना पसंद करता हूं।

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

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