2008-09-29 20 views
40

क्या उपयोग अपवाद पकड़ता है या इसे फेंक देता है? यानीसी # "प्रयोग" सिंटेक्स

using (StreamReader rdr = File.OpenText("file.txt")) 
{ 
//do stuff 
} 

यदि स्ट्रीमreader अपवाद फेंकता है तो इसे उपयोग या फेंककर पकड़ा जाता है ताकि कॉलिंग फ़ंक्शन इसे संभाल सके?

उत्तर

28

कथन का उपयोग अपवाद नहीं खाते हैं।

सभी "प्रयोग" आपके ऑब्जेक्ट को ब्लॉक का उपयोग करने का दायरा है, और जब यह ब्लॉक छोड़ देता है तो ऑब्जेक्ट पर स्वचालित रूप से निपटान() को कॉल करता है।

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

+7

मैं काफी हद तक निश्चित हूं कि आपका "गॉचा" सटीक नहीं है। चूंकि StreamReader क्लास IDISposable लागू करता है, इसलिए उपयोग कथन ऑब्जेक्ट के निपटारे का ख्याल रखेगा। चूंकि उपयोग कथन अंततः ब्लॉक की तरह कार्य करता है, इससे कोई फर्क नहीं पड़ता कि आपके पास अपवाद है या वापसी है। –

+12

http://msdn.microsoft.com/en-us/library/system.threading.threadabortexception.aspx के अनुसार, पकड़ें और आखिरकार कथन अभी भी निष्पादित किए गए हैं। अंततः ब्लॉक के रूप में "उपयोग" संकलन के बाद से, आपके उदाहरण में स्ट्रेड रीडर का निपटान किया जाएगा। – Uhall

+0

मैं पिछले दो टिप्पणियों के साथ सहमत होगा। उपरोक्त @ उहल की टिप्पणी के अलावा, थ्रेडएबॉर्ट अपवाद थ्रेड को निरस्त नहीं करता है, यह परिणामस्वरूप उठाए गए अपवाद को पकड़ता है। –

2

आप विशेष रूप से एक अपवाद यह ढेर फेंका है जब तक कुछ

15

using करता पकड़ने नहीं है, तो अपवाद के माध्यम से उबालने के लिए अनुमति देता है। यह एक कोशिश/आखिरकार काम करता है, जहां अंततः उपयोग की गई वस्तु का निपटान करता है। इस प्रकार, यह केवल उन वस्तुओं के लिए उपयुक्त/उपयोगी है जो IDisposable लागू करते हैं।

+0

+1। 'कोशिश/finally'। बहुत धन्यवाद! – xagyg

2

उपयोग अपने दायरे में सामान को साफ करने के अलावा अपवाद हैंडलिंग में हस्तक्षेप नहीं करता है।

यह अपवादों को संभाल नहीं करता है लेकिन अपवादों को पार करने देता है।

0

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

शायद सवाल यह है कि, अगर घोषणा में कोई त्रुटि हुई तो क्या यह ब्रांड्स में आवंटित संसाधनों का निपटान करेगा? हालांकि, दोनों हो रहा है कल्पना करना मुश्किल है।

60

जब आप एक कथन का उपयोग देखते हैं, इस कोड के बारे में सोच:

StreadReader rdr = null; 
try 
{ 
    rdr = File.OpenText("file.txt"); 
    //do stuff 
} 
finally 
{ 
    if (rdr != null) 
     rdr.Dispose(); 
} 

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

5

यह अपवाद फेंकता है, इसलिए या तो आपकी युक्त विधि को इसे संभालने की आवश्यकता है, या इसे ढेर को पास करना है।

try 
{ 
    using (
     StreamReader rdr = File.OpenText("file.txt")) 
    { //do stuff 
    } 
} 
catch (FileNotFoundException Ex) 
{ 
    // The file didn't exist 
} 
catch (AccessViolationException Ex) 
{ 
    // You don't have the permission to open this 
} 
catch (Exception Ex) 
{ 
    // Something happened! 
} 
2

using की गारंटी देता है * निर्मित ऑब्जेक्ट ब्लॉक के अंत में निपटारा किया जाएगा, भले ही एक अपवाद फेंक दिया है। अपवाद पकड़ा गया है। हालांकि, अगर आप इसे स्वयं पकड़ने की कोशिश करते हैं तो आपको सावधान रहना होगा कि आप क्या करते हैं। चूंकि अपवाद को पकड़ने वाला कोई भी कोड using कथन द्वारा परिभाषित स्कोप ब्लॉक के बाहर है, इसलिए आपका ऑब्जेक्ट उस कोड पर उपलब्ध नहीं होगा।

* बिजली की विफलता, परमाणु प्रलय, आदि जैसे सामान्य संदिग्धों को छोड़कर

1

आप कल्पना कर सकते एक के रूप में उपयोग करने का प्रयास ... अंत में कैच ब्लॉक के बिना ब्लॉक। अंत में ब्लॉक, IDisposable.Dispose कहा जाता है, और चूंकि कोई पकड़ ब्लॉक नहीं है, किसी भी अपवाद को ढेर फेंक दिया जाता है।

3

किसी भी अपवाद जो उपयोग कथन की प्रारंभिक अभिव्यक्ति में फेंक दिया गया है, विधि स्कोप का प्रचार करेगा और उम्मीद के अनुसार ढेर कॉल करेगा।

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

+0

यह हमेशा * व्यवहार * आप चाहते हैं। यदि कन्स्ट्रक्टर के अंदर कई प्रारंभिकता दफन की जाती है, तो यह किसी भी आवश्यक सफाई को प्रबंधित करने के लिए कन्स्ट्रक्टर तक है। कोई बाहरी कोड संभवतः ऐसा नहीं कर सकता है, क्योंकि वस्तु वास्तव में नहीं बनाई जाएगी। – Joe

+2

@ जो - मैं यहां स्मार्ट आवाज करने की कोशिश कर रहा हूं। मेरे तर्क में त्रुटियों को इंगित करना बंद करो! –

3

आपके उदाहरण में, File.OpenText फेंकता है, Dispose नहीं कहा जाएगा।

यदि //do stuff में अपवाद होता है, तो Dispose कहा जाएगा।

दोनों मामलों में, अपवाद सामान्य रूप से दायरे से प्रचारित होता है, क्योंकि यह कथन का उपयोग करके होगा।

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