इसलिए, मुझे पता है कि कोशिश / कैच कुछ ओवरहेड को जोड़ता है और इसलिए प्रक्रिया प्रवाह को नियंत्रित करने का एक अच्छा तरीका नहीं है, लेकिन यह ओवरहेड कहां से आता है और यह वास्तविक प्रभाव क्या है?
इसलिए, मुझे पता है कि कोशिश / कैच कुछ ओवरहेड को जोड़ता है और इसलिए प्रक्रिया प्रवाह को नियंत्रित करने का एक अच्छा तरीका नहीं है, लेकिन यह ओवरहेड कहां से आता है और यह वास्तविक प्रभाव क्या है?
जवाबों:
मैं भाषा कार्यान्वयन में एक विशेषज्ञ नहीं हूं (इसलिए इसे नमक के एक दाने के साथ लें), लेकिन मुझे लगता है कि सबसे बड़ी लागत में से एक है स्टैक को खोलना और स्टैक ट्रेस के लिए इसे संग्रहीत करना। मुझे संदेह है कि यह केवल तब होता है जब अपवाद फेंक दिया जाता है (लेकिन मुझे नहीं पता), और यदि ऐसा है, तो यह हर बार एक अपवाद को फेंक दिए जाने पर छिपी हुई लागत का आकार होगा ... इसलिए ऐसा नहीं है कि आप सिर्फ एक जगह से कूद रहे हैं दूसरे के कोड में, बहुत कुछ चल रहा है।
मुझे नहीं लगता कि यह एक समस्या है जब तक आप अपवाद व्यवहार के लिए अपवाद का उपयोग कर रहे हैं (इसलिए कार्यक्रम के माध्यम से आपके विशिष्ट, अपेक्षित पथ नहीं)।
यहां बनाने के लिए तीन बिंदु:
सबसे पहले, आपके कोड में वास्तव में ट्राइ-कैच ब्लॉक होने पर बहुत कम या कोई प्रदर्शन जुर्माना नहीं है। यह एक विचार नहीं होना चाहिए जब उन्हें अपने आवेदन में रखने से बचने की कोशिश की जाए। जब एक अपवाद फेंका जाता है तो प्रदर्शन हिट केवल खेल में आता है।
जब स्टैक अनइंडिंग ऑपरेशंस आदि के अलावा एक अपवाद को फेंक दिया जाता है, जो अन्य लोगों ने लिया है, तो आपको पता होना चाहिए कि रनटाइम / रिफ्लेक्शन संबंधित सामान का एक पूरा गुच्छा अपवाद वर्ग के सदस्यों को पॉप्युलेट करने के लिए होता है जैसे स्टैक ट्रेस। ऑब्जेक्ट और विभिन्न प्रकार के सदस्य आदि।
मेरा मानना है कि यह एक कारण है कि सामान्य सलाह यदि आप throw;
अपवाद को फिर से खत्म करने जा रहे हैं तो केवल अपवाद को फिर से फेंकने या एक नया निर्माण करें क्योंकि उन मामलों में सभी स्टैक जानकारी को फिर से व्यवस्थित किया जाता है जबकि सरल में फेंक यह सब संरक्षित है।
throw new Exception("Wrapping layer’s error", ex);
क्या आप कोशिश कर रहे हैं कि ओवर / कैच / ओवरऑल के उपयोग के बारे में पूछ रहे हैं, जब अपवाद नहीं फेंके गए हैं, या प्रक्रिया प्रवाह को नियंत्रित करने के लिए अपवाद का उपयोग करने का ओवरहेड है? उत्तरार्द्ध कुछ हद तक एक बच्चा के जन्मदिन की मोमबत्ती को रोशन करने के लिए डायनामाइट की एक छड़ी का उपयोग करने के लिए समान है, और संबंधित ओवरहेड निम्नलिखित क्षेत्रों में आता है:
गैर-निवासी कोड और डेटा को सामान्य रूप से आपके एप्लिकेशन के काम करने वाले सेट में नहीं पहुंचने के कारण आप अतिरिक्त पृष्ठ दोषों की अपेक्षा कर सकते हैं।
उपरोक्त दोनों आइटम आम तौर पर "कोल्ड" कोड और डेटा तक पहुंचते हैं, इसलिए यदि आपके पास स्मृति दबाव है, तो कठिन पृष्ठ दोष संभावित हैं:
लागत के वास्तविक प्रभाव के लिए, यह आपके कोड में उस समय क्या चल रहा है, इसके आधार पर बहुत भिन्न हो सकता है। जॉन स्कीट का यहां एक अच्छा सारांश है , जिसमें कुछ उपयोगी लिंक हैं। मैं उनके इस कथन से सहमत हूं कि यदि आप उस बिंदु पर पहुंच जाते हैं जहां अपवाद आपके प्रदर्शन को काफी नुकसान पहुंचा रहे हैं, तो आपको केवल प्रदर्शन से परे अपने अपवादों के उपयोग के संदर्भ में समस्याएं हैं।
मेरे अनुभव में सबसे बड़ा ओवरहेड वास्तव में एक अपवाद को फेंकना और उसे संभालना है। मैंने एक बार एक परियोजना पर काम किया था जहां किसी व्यक्ति को किसी वस्तु को संपादित करने का अधिकार था या नहीं, यह जांचने के लिए कोड के समान कोड का उपयोग किया गया था। प्रस्तुति की परत में हर जगह इस हसरत () पद्धति का उपयोग किया गया था, और अक्सर 100 वस्तुओं के लिए बुलाया जाता था।
bool HasRight(string rightName, DomainObject obj) {
try {
CheckRight(rightName, obj);
return true;
}
catch (Exception ex) {
return false;
}
}
void CheckRight(string rightName, DomainObject obj) {
if (!_user.Rights.Contains(rightName))
throw new Exception();
}
जब परीक्षण डेटा के साथ परीक्षण डेटाबेस फुलर हो गया, तो यह नए रूपों आदि को खोलते हुए बहुत ही धीमी गति से आगे बढ़ता है।
इसलिए मैंने इसे निम्नलिखित में बदल दिया, जो - बाद में त्वरित 'एन गंदे मापों के अनुसार - तीव्रता के 2 क्रमों के बारे में तेज़ी से है:
bool HasRight(string rightName, DomainObject obj) {
return _user.Rights.Contains(rightName);
}
void CheckRight(string rightName, DomainObject obj) {
if (!HasRight(rightName, obj))
throw new Exception();
}
इसलिए संक्षेप में, सामान्य प्रक्रिया प्रवाह में अपवादों का उपयोग करना परिमाण के दो क्रमों के बारे में है, फिर अपवादों के बिना समान प्रक्रिया प्रवाह का उपयोग करना।
आम तौर पर स्वीकृत सिद्धांतों के विपरीत, try
/ catch
महत्वपूर्ण प्रदर्शन निहितार्थ हो सकते हैं, और यह है कि एक अपवाद फेंक दिया गया है या नहीं!
पिछले कुछ वर्षों में Microsoft MVP द्वारा ब्लॉग पोस्ट के एक जोड़े में कवर किया गया है, और मुझे विश्वास है कि आप उन्हें आसानी से पा सकते हैं अभी तक StackOverflow सामग्री के बारे में बहुत परवाह करता है इसलिए मैं उनमें से कुछ को भराव सबूत के रूप में लिंक प्रदान करूंगा :
try
catch
finally
पीटर रिची द्वारा / / ( और भाग दो ) के प्रदर्शन निहितार्थ , उन आशाओं की पड़ताल करते हैं, जोtry
/catch
/finally
अक्षम करते हैं (और मैं मानक से उद्धरण के साथ इसमें आगे जाऊंगा)Parse
बनाम TryParse
बनामConvertTo
इयान हफ द्वारा स्पष्ट रूप से कहा गया है कि "अपवाद हैंडलिंग बहुत धीमी है" और इस बिंदुको एक दूसरे के खिलाफथपथपाकरInt.Parse
औरप्रदर्शितकरता हैInt.TryParse
... जो भी व्यक्तिपर्दे के पीछे/TryParse
उपयोग करने काआग्रहकरता है, उसे कुछ प्रकाश डालना चाहिए!try
catch
यह उत्तर भी है जो असंतुष्ट कोड के बीच अंतर को दिखाता है- और बिना उपयोग किए try
/ catch
।
यह बहुत स्पष्ट लगता है कि है एक ओवरहेड जो कोड पीढ़ी में तो एकदम मानने योग्य है, और कहा कि भूमि के ऊपर भी जो माइक्रोसॉफ्ट मूल्य लोगों द्वारा स्वीकार किया जा रहा है! फिर भी मैं इंटरनेट को दोहरा रहा हूं ...
हां, कोड की एक तुच्छ रेखा के लिए दर्जनों अतिरिक्त MSIL निर्देश हैं, और यह अक्षम अनुकूलन को भी कवर नहीं करता है, इसलिए तकनीकी रूप से यह एक माइक्रो-ऑप्टिमाइज़ेशन है।
मैंने एक उत्तर वर्ष पहले पोस्ट किया था जो प्रोग्रामर (मैक्रो-ऑप्टिमाइज़ेशन) की उत्पादकता पर केंद्रित होने के कारण हटा दिया गया था।
यह दुर्भाग्यपूर्ण है क्योंकि यहां कुछ नैनोसेकंडों की बचत नहीं हुई है और सीपीयू का समय मनुष्यों द्वारा मैनुअल अनुकूलन के कई संचित घंटों के लिए बनाए जाने की संभावना है। आपका बॉस किसके लिए अधिक भुगतान करता है: आपके समय का एक घंटा, या कंप्यूटर चलाने के साथ एक घंटा? किस बिंदु पर हम प्लग खींचते हैं और स्वीकार करते हैं कि यह सिर्फ एक तेज कंप्यूटर खरीदने का समय है ?
स्पष्ट रूप से, हमें अपनी प्राथमिकताओं का अनुकूलन करना चाहिए , न कि केवल हमारे कोड का! अपने अंतिम उत्तर में मैंने कोड के दो स्निपेट के बीच के अंतरों को आकर्षित किया।
का उपयोग कर try
/ catch
:
int x;
try {
x = int.Parse("1234");
}
catch {
return;
}
// some more code here...
उपयोग नहीं try
/ catch
:
int x;
if (int.TryParse("1234", out x) == false) {
return;
}
// some more code here
एक रखरखाव डेवलपर के दृष्टिकोण से विचार करें, जो आपके समय को बर्बाद करने की अधिक संभावना है, अगर प्रोफाइलिंग / ऑप्टिमाइज़ेशन में नहीं (ऊपर कवर किया गया है), जो संभवतः भी आवश्यक नहीं होगा यदि यह try
/ catch
समस्या के लिए नहीं था , तो स्क्रॉलिंग के माध्यम से स्रोत कोड ... उनमें से एक में बॉयलरप्लेट कचरा की चार अतिरिक्त लाइनें हैं!
जैसा कि अधिक से अधिक क्षेत्रों को एक वर्ग में पेश किया जाता है, यह सभी बॉयलरप्लेट कचरा जमा करता है (दोनों स्रोत और असंतुष्ट कोड में) उचित स्तर से परे। प्रति फ़ील्ड चार अतिरिक्त लाइनें, और वे हमेशा एक ही रेखाएँ होती हैं ... क्या हमें खुद को दोहराने से बचने के लिए नहीं सिखाया गया था? मुझे लगता है कि हम कुछ होम-ब्रूअड एब्सट्रैक्ट के पीछे try
/ छिप सकते हैं catch
, लेकिन ... फिर हम अपवादों (यानी उपयोग Int.TryParse
) से बच सकते हैं ।
यह एक जटिल उदाहरण भी नहीं है; मैंने try
/ में नई कक्षाओं को तुरंत शुरू करने के प्रयास देखे हैं catch
। इस बात पर विचार करें कि कंस्ट्रक्टर के अंदर सभी कोड को तब कुछ अनुकूलन से अयोग्य ठहराया जा सकता है जो अन्यथा संकलक द्वारा स्वचालित रूप से लागू किया जाएगा। इस सिद्धांत को जन्म देने के लिए बेहतर तरीका क्या है कि कंपाइलर धीमा है , क्योंकि कंपाइलर का विरोध ठीक उसी तरह हो रहा है जैसा कि उसे बताया जाता है ?
उक्त कंस्ट्रक्टर द्वारा एक अपवाद मान लिया गया है, और कुछ बग को ट्रिगर किया गया है, जिसके परिणामस्वरूप खराब रखरखाव डेवलपर को फिर इसे ट्रैक करना होगा। यह इतना आसान काम नहीं हो सकता है, क्योंकि गोटो दुःस्वप्न के स्पेगेटी कोड के विपरीत , try
/ तीन आयामोंcatch
में गड़बड़ी पैदा कर सकता है , क्योंकि यह स्टैक को न केवल एक ही विधि के अन्य भागों में स्थानांतरित कर सकता है, बल्कि अन्य कक्षाएं और विधियां भी हो सकती हैं। , जो सभी रखरखाव डेवलपर, कठिन तरीके से देखा जाएगा ! फिर भी हमें बताया गया है कि "गोटो खतरनाक है", हे!
अंत में मैं उल्लेख करता हूं, try
/ catch
इसका लाभ है जो है, इसे अनुकूलन को अक्षम करने के लिए डिज़ाइन किया गया है ! यह है, अगर आप करेंगे, एक डिबगिंग सहायता ! यही कारण है कि यह के लिए डिजाइन किया गया था और यह है कि यह के रूप में इस्तेमाल किया जाना चाहिए ...
मुझे लगता है कि यह एक सकारात्मक बिंदु भी है। इसका उपयोग उन आशाओं को अक्षम करने के लिए किया जा सकता है जो अन्यथा सुरक्षित, बहुस्तरीय अनुप्रयोगों के लिए सुरक्षित मैसेज पासिंग एल्गोरिदम, और संभावित दौड़ की स्थिति को पकड़ने के लिए;) हो सकता है कि केवल एक ही परिदृश्य के बारे में मैं कोशिश / पकड़ का उपयोग करने के बारे में सोच सकता हूं। यहां तक कि इसके विकल्प भी हैं।
क्या अनुकूलन करते हैं try
, catch
और finally
अक्षम करते हैं?
उर्फ
कैसे हैं try
, catch
और finally
एड्स डिबगिंग के रूप में उपयोगी?
वे लिखते हैं-बाधाएँ। यह मानक से आता है:
12.3.3.13 ट्राइ-कैच स्टेटमेंट्स
एक बयान के लिए stmt फार्म की:
try try-block catch ( ... ) catch-block-1 ... catch ( ... ) catch-block-n
- के निश्चित काम राज्य वी की शुरुआत में कोशिश-ब्लॉक के निश्चित काम राज्य के रूप में ही है वी की शुरुआत में stmt ।
- के निश्चित काम राज्य वी की शुरुआत में पकड़-ब्लॉक-मैं (किसी के लिए मैं ) के निश्चित काम राज्य के रूप में ही है वी की शुरुआत में stmt ।
- Stmt के अंतिम-बिंदु पर v की निश्चित असाइनमेंट स्थिति निश्चित रूप से असाइन की गई है (और केवल अगर) v को निश्चित रूप से ट्राइ -ब्लॉक और प्रत्येक कैच-ब्लॉक-आई के अंत-बिंदु पर सौंपा गया है (प्रत्येक i से n के लिए) )।
दूसरे शब्दों में, प्रत्येक try
कथन की शुरुआत में :
try
बयान दर्ज करने से पहले दृश्यमान वस्तुओं के लिए किए गए सभी असाइनमेंट पूरे होने चाहिए, जिसमें एक शुरुआत के लिए थ्रेड लॉक की आवश्यकता होती है, जिससे यह डीबगिंग की स्थिति के लिए उपयोगी होता है!try
बयान से पहले असाइन किए गए हैंप्रत्येक catch
कथन के लिए एक समान कहानी होती है ; मान लें कि आपके try
कथन के भीतर (या एक रचनाकार या यह कार्य करता है, आदि) आप उस अन्यथा निरर्थक चर (यह कहते हैं garbage=42;
) को असाइन करते हैं, संकलक उस कथन को समाप्त नहीं कर सकता है, भले ही यह कार्यक्रम के अचूक व्यवहार के लिए कितना भी अप्रासंगिक हो। । ब्लॉक में प्रवेश करने से पहले असाइनमेंट पूरा करना होगा catch
।
जो इसके लायक है, finally
वह इसी तरह की अपमानजनक कहानी बताता है :
12.3.3.14 कोशिश-अंत में बयान
एक के लिए कोशिश बयान stmt फार्म की:
try try-block finally finally-block
• के निश्चित काम राज्य वी की शुरुआत में कोशिश-ब्लॉक के निश्चित काम राज्य के रूप में ही है वी की शुरुआत में stmt ।
• के निश्चित काम राज्य वी की शुरुआत में अंत में ब्लॉक के निश्चित काम राज्य के रूप में ही है वी की शुरुआत में stmt ।
• stmt के अंतिम बिंदु पर v की निश्चित असाइनमेंट स्थिति निश्चित रूप से (और केवल यदि) या तो असाइन की गई है : o v निश्चित रूप से try-block o v के अंतिम बिंदु पर असाइन की गई हैनिश्चित रूप से अंत-ब्लॉक के अंत बिंदु पर सौंपा गया है यदि एक नियंत्रण प्रवाह हस्तांतरण (जैसे कि एक गोटो बयान) बनाया जाता है, जो कि कोशिश-ब्लॉक के भीतर शुरू होता है , और कोशिश-ब्लॉक के बाहर समाप्त होता है , तो v को भी निश्चित रूप से उस पर सौंपा गया माना जाता है नियंत्रण प्रवाह अंतरण अगर v निश्चित रूप से अंत-ब्लॉक के अंतिम बिंदु पर सौंपा गया है । (यह केवल एक ही नहीं है - यदि v निश्चित रूप से इस नियंत्रण प्रवाह हस्तांतरण पर किसी अन्य कारण से असाइन किया गया है, तो यह अभी भी निश्चित रूप से असाइन किया गया है।)
12.3.3.15 ट्राइ-कैच-आखिर स्टेटमेंट्स
एक कोशिश के लिए निश्चित असाइनमेंट विश्लेषण - पकड़ - अंत में फार्म का बयान:
try try-block catch ( ... ) catch-block-1 ... catch ( ... ) catch-block-n finally finally-block
किया जाता है के रूप में अगर बयान एक थे कोशिश - अंत में बयान एक enclosing कोशिश - पकड़ बयान:
try { try try-block catch ( ... ) catch-block-1 ... catch ( ... ) catch-block-n } finally finally-block
यह उल्लेख करने के लिए नहीं कि क्या यह एक बार-बार विधि के अंदर है, यह अनुप्रयोग के समग्र व्यवहार को प्रभावित कर सकता है।
उदाहरण के लिए, मैं ज्यादातर मामलों में Int32.Parse के उपयोग को एक बुरा अभ्यास मानता हूं क्योंकि यह किसी ऐसी चीज के अपवाद को फेंकता है जिसे अन्यथा आसानी से पकड़ा जा सकता है।
इसलिए यहां लिखी गई हर चीज को समाप्त करने के लिए:
1) अप्रत्याशित त्रुटियों को पकड़ने के लिए try..catch ब्लॉकों का उपयोग करें - लगभग कोई प्रदर्शन जुर्माना नहीं।
2) यदि आप इसे से बच सकते हैं तो अपवादित त्रुटियों के अपवादों का उपयोग न करें।
मैंने थोड़ी देर पहले इस बारे में एक लेख लिखा था क्योंकि उस समय बहुत सारे लोग इस बारे में पूछ रहे थे। आप इसे और http://www.blackwasp.co.uk/SpeedTestTryCatch.aspx पर परीक्षण कोड पा सकते हैं ।
उतावलापन यह है कि एक कोशिश / कैच ब्लॉक के लिए ओवरहेड की एक छोटी मात्रा है लेकिन इतना छोटा है कि इसे अनदेखा किया जाना चाहिए। हालाँकि, यदि आप लाखों बार निष्पादित किए गए लूप में कोशिश / कैच ब्लॉक चला रहे हैं, तो आप संभव हो तो ब्लॉक को लूप के बाहर ले जाने पर विचार कर सकते हैं।
जब आप वास्तव में अपवाद को पकड़ते हैं, तो कोशिश / कैच ब्लॉक के साथ महत्वपूर्ण प्रदर्शन समस्या होती है। यह आपके आवेदन में ध्यान देने योग्य विलंब जोड़ सकता है। बेशक, जब चीजें गलत हो रही हैं, तो अधिकांश डेवलपर्स (और बहुत सारे उपयोगकर्ता) एक अपवाद के रूप में ठहराव को पहचानते हैं जो होने वाला है! यहां कुंजी सामान्य संचालन के लिए अपवाद हैंडलिंग का उपयोग नहीं करना है। जैसा कि नाम से पता चलता है, वे असाधारण हैं और आपको उन्हें फेंके जाने से बचने के लिए सब कुछ करना चाहिए। आपको उन प्रोग्राम के अपेक्षित प्रवाह के हिस्से के रूप में उपयोग नहीं करना चाहिए जो सही ढंग से काम कर रहे हैं।
मैंने पिछले साल इस विषय के बारे में एक ब्लॉग प्रविष्टि की । इसकी जांच - पड़ताल करें। लब्बोलुआब यह है कि अगर कोई अपवाद नहीं होता है, तो एक कोशिश ब्लॉक के लिए लगभग कोई लागत नहीं है - और मेरे लैपटॉप पर, एक अपवाद लगभग 36μs था। यह आपकी अपेक्षा से कम हो सकता है, लेकिन ध्यान रखें कि वे परिणाम जहां उथले स्टैक पर हैं। इसके अलावा, पहले अपवाद वास्तव में धीमा हैं।
try
/ catch
बहुत अधिक? हे हेह), लेकिन आप भाषा कल्पना और कुछ एमएस एमवीपी के साथ बहस कर रहे हैं जिन्होंने इस विषय पर ब्लॉग भी लिखा है, माप प्रदान करते हैं आपकी सलाह के विपरीत ... मैं सुझाव के लिए खुला हूं कि मैंने जो शोध किया है वह गलत है, लेकिन मुझे यह देखने के लिए आपके ब्लॉग प्रविष्टि को पढ़ने की आवश्यकता होगी।
try-catch
ब्लॉक बनाम tryparse()
विधियों को लक्षित करता है , लेकिन अवधारणा समान है।
कंपाइलर एरर मैसेज, कोड-एनालिसिस वार्निंग मैसेज और रूटीन एक्सेप्टेड एक्सेप्टेंस (विशेषकर अपवाद जो एक जगह फेंके जाते हैं और दूसरे में स्वीकार किए जाते हैं) से मुक्त कोड लिखना, डिबग करना और बनाए रखना बहुत आसान है। क्योंकि यह आसान है, कोड औसत रूप से बेहतर लिखित और कम छोटी होगी।
मेरे लिए, प्रोग्रामर और गुणवत्ता ओवरहेड प्रक्रिया प्रवाह के लिए ट्राइ-कैच का उपयोग करने के खिलाफ प्राथमिक तर्क है।
अपवादों का कंप्यूटर ओवरहेड तुलना में नगण्य है, और आमतौर पर वास्तविक-विश्व प्रदर्शन आवश्यकताओं को पूरा करने के लिए आवेदन की क्षमता के मामले में छोटा है।
मैं वास्तव में हफ़थोर के ब्लॉग पोस्ट को पसंद करता हूं , और इस चर्चा में अपने दो सेंट जोड़ने के लिए, मैं यह कहना चाहता हूं कि, मेरे लिए हमेशा यह आसान रहा है कि डेटा लेयर को केवल एक प्रकार का अपवाद (डेटाअटेक्सेप्शन) फेंक दें। इस तरह से मेरा बिजनेस लाईर जानता है कि उसे क्या उम्मीद है और वह उसे पकड़ता है। फिर आगे के व्यावसायिक नियमों (यानी यदि मेरी व्यावसायिक वस्तु वर्कफ़्लो आदि में भाग लेती है) के आधार पर, मैं एक नया अपवाद (BusinessObjectException) फेंक सकता हूं या फिर से / फेंक दिए बिना आगे बढ़ सकता हूं।
मैं कहूंगा कि कोशिश करने में संकोच न करें..जब भी आवश्यक हो और इसे बुद्धिमानी से उपयोग करें!
उदाहरण के लिए, यह विधि वर्कफ़्लो में भाग लेती है ...
टिप्पणियाँ?
public bool DeleteGallery(int id)
{
try
{
using (var transaction = new DbTransactionManager())
{
try
{
transaction.BeginTransaction();
_galleryRepository.DeleteGallery(id, transaction);
_galleryRepository.DeletePictures(id, transaction);
FileManager.DeleteAll(id);
transaction.Commit();
}
catch (DataAccessException ex)
{
Logger.Log(ex);
transaction.Rollback();
throw new BusinessObjectException("Cannot delete gallery. Ensure business rules and try again.", ex);
}
}
}
catch (DbTransactionException ex)
{
Logger.Log(ex);
throw new BusinessObjectException("Cannot delete gallery.", ex);
}
return true;
}
हम माइकल एल स्कॉट द्वारा प्रोग्रामिंग लैंग्वेजेज प्रैग्मैटिक्स में पढ़ सकते हैं कि आजकल के कंपाइलर्स सामान्य मामले में कोई ओवरहेड नहीं जोड़ते हैं, इसका मतलब है, जब कोई अपवाद नहीं होता है। इसलिए हर काम संकलन समय में किया जाता है। लेकिन जब एक अपवाद रन-टाइम में फेंक दिया जाता है, तो कंपाइलर को सही अपवाद खोजने के लिए एक द्विआधारी खोज करने की आवश्यकता होती है और यह आपके द्वारा बनाए गए हर नए थ्रो के लिए होगा।
लेकिन अपवाद अपवाद हैं और यह लागत पूरी तरह से स्वीकार्य है। यदि आप अपवादों के बिना एक्सेप्शन हैंडलिंग करने की कोशिश करते हैं और इसके बजाय रिटर्न एरर कोड का उपयोग करते हैं, तो शायद आपको प्रत्येक सबरूटीन के लिए एक स्टेटमेंट की आवश्यकता होगी और यह वास्तव में वास्तविक समय में ओवरहेड होगा। आप जानते हैं कि यदि कोई कथन कुछ विधानसभा निर्देशों में परिवर्तित हो जाता है, तो आपके उप-रूटीन में प्रवेश करने पर हर बार प्रदर्शन किया जाएगा।
मेरी अंग्रेजी के बारे में क्षमा करें, आशा है कि यह आपकी मदद करती है। यह जानकारी उद्धृत पुस्तक पर आधारित है, अधिक जानकारी के लिए अध्याय 8.5 अपवाद हैंडलिंग से संबंधित है।
जब उपयोग किया जाना चाहिए, जहां उपयोग नहीं किया जाना चाहिए, तब हमें एक कोशिश / कैच ब्लॉक की सबसे बड़ी संभावित लागतों में से एक का विश्लेषण करें:
int x;
try {
x = int.Parse("1234");
}
catch {
return;
}
// some more code here...
और यहाँ एक कोशिश के बिना / पकड़ है:
int x;
if (int.TryParse("1234", out x) == false) {
return;
}
// some more code here
महत्वहीन श्वेत-अंतरिक्ष की गिनती नहीं, कोई यह देख सकता है कि कोड के ये दो समान टुकड़े बाइट्स में लगभग समान लंबाई के हैं। उत्तरार्द्ध में 4 बाइट्स कम इंडेंटेशन शामिल हैं। क्या यह गलत बात है?
चोट के अपमान को जोड़ने के लिए, एक छात्र लूप का फैसला करता है जबकि इनपुट को इंट के रूप में पार्स किया जा सकता है। बिना कोशिश / पकड़ने के समाधान कुछ इस तरह हो सकता है:
while (int.TryParse(...))
{
...
}
लेकिन कोशिश / कैच का उपयोग करते समय यह कैसा दिखता है?
try {
for (;;)
{
x = int.Parse(...);
...
}
}
catch
{
...
}
ट्राई / कैच ब्लॉक इंडेंटेशन को बर्बाद करने के जादुई तरीके हैं, और हम अभी भी इसका कारण नहीं जानते हैं कि यह विफल रहा है! कल्पना करें कि डिबगिंग करने वाला व्यक्ति कैसा महसूस करता है, जब कोड एक अच्छा स्पष्ट अपवाद त्रुटि के साथ रुकने के बजाय एक गंभीर तार्किक दोष को निष्पादित करना जारी रखता है। कोशिश / पकड़ ब्लॉक एक आलसी आदमी के डेटा सत्यापन / स्वच्छता हैं।
छोटी लागतों में से एक यह है कि कोशिश / कैच ब्लॉक वास्तव में कुछ अनुकूलन को अक्षम करते हैं: http://msmvps.com/blogs/peterritchie/archive/2007/06/22/performance-implication-of-try-catch-finally.aspx । मुझे लगता है कि यह एक सकारात्मक बिंदु भी है। इसका उपयोग उन आशाओं को निष्क्रिय करने के लिए किया जा सकता है जो अन्यथा सुरक्षित, बहुस्तरीय अनुप्रयोगों के लिए सुरक्षित मैसेज पासिंग एल्गोरिदम, और संभावित दौड़ की स्थिति को पकड़ने के लिए हो सकता है;) यह एकमात्र परिदृश्य है जिसके बारे में मैं कोशिश / पकड़ का उपयोग करने के बारे में सोच सकता हूं। यहां तक कि इसके विकल्प भी हैं।
Int.Parse
इसके पक्ष में बचते हैं Int.TryParse
।