2008-09-08 16 views
28

सिंटेक्स एक तरफ,आखिरकार ब्लॉक का बिंदु क्या है? .NET 2.0 में:

try { 
} 
catch() { 
} 
finally { 
    x = 3; 
} 

और

try { 
} 
catch() { 
} 

x = 3; 

संपादित के बीच क्या अंतर है?


तो

try { 
    throw something maybe 
    x = 3 
} 
catch (...) { 
    x = 3 
} 

व्यवहार बराबर है?

+0

आप एक प्रोग्रामिंग भाषा निर्दिष्ट करना चाहेंगे। भाषा के आधार पर व्यवहार अलग-अलग होगा। –

+0

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

+0

मैं पिछली टिप्पणियों से सहमत हूं, आपको वास्तविक भाषा पर स्पष्टीकरण देना होगा और दिए गए उत्तरों की गंभीरता से समीक्षा करना होगा। अपरिवर्तित उत्तर या तो गलत या अपूर्ण हैं। –

उत्तर

32

भाषा पर निर्भर करता है क्योंकि कुछ मामूली अर्थपूर्ण मतभेद हो सकते हैं, लेकिन विचार यह है कि यह हमेशा (लगभग) निष्पादित करेगा, भले ही प्रयास ब्लॉक में कोड अपवाद फेंक दिया हो।

दूसरे उदाहरण में, यदि कैच ब्लॉक में कोड लौटाता है या छोड़ देता है, तो x = 3 निष्पादित नहीं किया जाएगा। पहले में यह होगा।

नेट मंच में, कुछ मामलों में अंत में ब्लॉक के निष्पादन घटित नहीं होगा: सुरक्षा अपवाद, थ्रेड निलंबन, कंप्यूटर को शट डाउन :), आदि

+2

मैं उन तरीकों की सूची में जोड़ूंगा जो आखिरकार * पर्यावरण। एक्सिट * कॉल को अवरुद्ध करने के निष्पादन को रोकें। – Luca

0

तो आप कोशिश ब्लॉक में शुरू किए गए किसी भी खुले कनेक्शन आदि को साफ कर सकते हैं। यदि आपने कोई कनेक्शन खोला है और फिर एक अपवाद हुआ है, तो वह अपवाद ठीक से बंद नहीं होगा। इस प्रकार का परिदृश्य अंततः ब्लॉक के लिए है।

10

जावा में:

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

37

खैर, एक बात के लिए, अगर आप अपने प्रयास ब्लॉक के अंदर वापस आते हैं, अंततः अभी भी चलेंगे, लेकिन कोशिश-अंत-अंत में ब्लॉक के नीचे सूचीबद्ध कोड नहीं होगा।

+0

इस वास्तविक उत्तर पर विचार नहीं करेगा - तथ्य का एक बयान ... – Ian

+0

सेकेंड! मैं कहूंगा कि यह "जवाब" नहीं है .. –

+1

आप सही हैं। यह एक अच्छा जवाब है, लेकिन मुझे लगता है कि यह सीधे बताए गए प्रश्न का उत्तर नहीं देता है। शायद इसका मतलब है कि मुझे एक बेहतर सवाल पूछा जाना चाहिए :) – Keshi

0

आखिरकार ब्लॉक निष्पादित करना है कि आपने अपवाद पकड़ा है या नहीं। Try/Catch/Finally example

2

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

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

आम तौर पर अंततः अपने आप को साफ करने के लिए उपयोग किया जाता है (बंद डीबी-कनेक्शन, फ़ाइल-हैंडल और पसंद)।

आप एक अंत में नियंत्रण-बयान (वापसी, ब्रेक, जारी रखने के लिए) का उपयोग कभी नहीं करना चाहिए, क्योंकि यह एक रखरखाव बुरा सपना हो सकता है और इसलिए खराब व्यवहार का

1

अंत में ब्लॉक हमेशा (बुलाया जाएगा अच्छी तरह से वास्तव में नहीं माना जाता है always ...) भले ही कोई अपवाद फेंक दिया गया हो या वापसी का बयान पूरा हो गया हो (हालांकि यह भाषा निर्भर हो सकता है)। यह साफ करने का एक तरीका है कि आपको हमेशा पता चल जाएगा।

+0

मैंने हमेशा आपके द्वारा लिंक किए गए दैनिक डब्ल्यूटीएफ आलेख से प्यार किया है - विशेष रूप से उन टिप्पणियों में से एक जो सुझाव देता है कि हमें एक जादू की आवश्यकता है फेफरी में, जो कि बिना किसी शक्ति के निष्पादित करने की गारंटी है! –

0

@Ed, आप catch(...) जैसे कुछ के बारे में सोच रहे हैं जो सी ++ में एक गैर-निर्दिष्ट अपवाद को पकड़ता है।

लेकिन finally कोड है जो catch ब्लॉक में क्या होता है कोई फर्क नहीं पड़ता। ताकि आप सभी चर के अंदर परिभाषित के लिए उपयोग होगा

माइक्रोसॉफ्ट, try-finally for C#

0

पर एक सहायता पृष्ठ अंत में ब्लॉक ट्राई/कैच के रूप में ही दायरे में है।

कल्पना कीजिए कि आपके पास एक फ़ाइल हैंडलर है, यह इस बात में अंतर है कि यह कैसे लिखा जाएगा।

try 
{ 
    StreamReader stream = new StreamReader("foo.bar"); 
    stream.write("foo"); 
} 
catch(Exception e) { } // ignore for now 
finally 
{ 
    stream.close(); 
} 

StreamReader stream = null; 
try 
{ 
    stream = new StreamReader("foo.bar"); 
    stream.write("foo"); 
} catch(Exception e) {} // ignore 

if (stream != null) 
    stream.close(); 

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

+0

कृपया एक भाषा को परिभाषित करें, क्योंकि यह आपके उत्तर में निहित है लेकिन कहा नहीं गया है। – shsteimer

+0

एक स्टैक ओवरफ्लो अंततः निष्पादित न करने का कारण बनता है। –

+1

मुझे लगता है कि पहला कोड नमूना गलत है (सी # में) - "कोशिश" ब्लॉक में घोषित चर * नहीं * पकड़ में अंतराल में या आखिरकार ब्लॉक में हैं। मैंने इसे एक परीक्षण सी # अनुप्रयोग में करने की कोशिश की और आखिरकार ब्लॉक संदर्भ पर संकलन-समय त्रुटि मिली: "नाम 'स्ट्रीम' वर्तमान संदर्भ में मौजूद नहीं है"। –

0

अंत में कोई भी कोड एक अनचाहे अपवाद की स्थिति में भी चलाया जाता है। आम तौर पर आखिरकार कोड का उपयोग अप्रत्याशित कोड की स्थानीय घोषणाओं को साफ करने के लिए किया जाता है। डिस्प्ले()।

9

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

आप इस उदाहरण का प्रयास करें:

try { 
    return 0; 
} finally { 
    return 2; 
} 

परिणाम होगा 2 :)

अन्य भाषाओं के लिए तुलना: Return From Finally

+0

ध्यान रखें कि अंत में ब्लॉक हमेशा निष्पादित नहीं होता है। एक स्टैकओवरफ्लो (इरादा नहीं है) अंत में ब्लॉक निष्पादित नहीं करेगा। –

+1

परिणाम जावा में 2 होगा। सी # में इस कोड को संकलित नहीं किया जा सकता है। – thorn

0

अंत में ब्लॉक,, आप की अनुमति एक डेवलपर के रूप को साफ़ रखने के लिए अपने आप के बाद, कोशिश में कोड को आगे बढ़ाने के कार्यों के बावजूद {} ब्लॉक में त्रुटियों को अवरुद्ध कर दिया गया है, और दूसरों ने इसे इंगित किया है, मुख्य रूप से मुक्त संसाधनों की छतरी के नीचे गिरता है - समापन पॉइंटर्स/सॉकेट/परिणाम सेट, कनेक्शन लौटाना एक पूल आदि

@mats बहुत सही है हमेशा "हार्ड" असफलताओं के लिए क्षमता है - अंत में ब्लॉक महत्वपूर्ण मिशन कोड शामिल नहीं होना चाहिए, जो हमेशा कोशिश {}

अंदर transactionally किया जाना चाहिए - @mats फिर से वास्तविक सुंदरता यह आप अपवाद वापस अपने स्वयं के तरीकों में से बाहर फेंक, और अभी भी यह गारंटी है कि आप को साफ़ रखने की अनुमति देता है:

try 
{ 
StreamReader stream = new StreamReader("foo.bar"); 
mySendSomethingToStream(stream); 
} 
catch(noSomethingToSendException e) { 
    //Swallow this  
    logger.error(e.getMessage()); 
} 
catch(anotherTypeOfException e) { 
    //More serious, throw this one back 
    throw(e); 
} 
finally 
{ 
stream.close(); 
} 

तो, हम अपवाद के कई प्रकार पकड़ कर सकते हैं, उन्हें प्रक्रिया अलग ढंग से (पहला प्रयास {}, दूसरा प्रभावी रूप से रिटर्न) से परे किसी भी चीज़ के लिए निष्पादन की अनुमति देता है, लेकिन हमेशा अच्छी तरह से और स्पष्ट रूप से साफ़ हो जाता है।

4

वहाँ कई चीजें हैं जो एक अंत में उपयोगी ब्लॉक कर रहे हैं:

  1. आप कोशिश या पकड़ ब्लॉक से वापस करते हैं, अंत में ब्लॉक अभी भी निष्पादित किया जाता है, ठीक से पहले नियंत्रण बुला समारोह को वापस दिया जाता है
  2. यदि कैच ब्लॉक में कोई अपवाद होता है, या कोशिश ब्लॉक में एक अपर्याप्त अपवाद होता है, तो अंत में ब्लॉक में कोड अभी भी निष्पादित होता है।

ये अंततः फाइल हैंडल या सॉकेट बंद करने के लिए उत्कृष्ट ब्लॉक बनाते हैं।

1

@iAn और @mats:

मैं में कुछ भी "फाड़" नहीं होगा अंत में {} कि किया गया था "सेट अप" कोशिश {} एक नियम के रूप में। {{} प्रयास के बाहर स्ट्रीम निर्माण को खींचना बेहतर होगा। यदि आपको स्ट्रीम पर अपवाद को संभालने की आवश्यकता है तो इसे अधिक दायरे में किया जा सकता है।

StreamReader stream = new StreamReader("foo.bar"); 
try { 
    mySendSomethingToStream(stream); 
} 
catch(noSomethingToSendException e) { 
    //Swallow this  
    logger.error(e.getMessage()); 
} 
catch(anotherTypeOfException e) { 
    //More serious, throw this one back 
    throw(e); 
} 
finally { 
    stream.close(); 
} 
+0

बस एक नोट लाइन 'फेंक (ई); // रीराइट्स स्टैक ट्रेस ' 'थ्रो से अलग है; // मूल अपवाद को फिर से फेंकता है – vitule

0

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

उदाहरण के लिए, डेटाबेस सत्र या जेएमएस कनेक्शन बंद करना, या कुछ ओएस संसाधन को हटाना।

मुझे लगता है कि यह .NET में समान है?

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