2011-06-23 9 views
5

मैंब्लॉक का उपयोग निगलने अपवाद

void foo1() 
{ 
    using(...){...} 
} 

void foo2() 
{ 
    using(...){...} 
} 

void foo3() 
{ 
    using(...){...} 
} 

है और मैं

void foo() 
{ 
    ... 
    backgroundWorker.DoWork += (s, ev) => 
              { 
               try 
               { 
                foo1(); 
                foo2(); 
                foo3(); 
               } 
               catch (Exception ex) 
               { 
                // log ex 
               } 
              }; 
     ...  
} 

है और मैं अभी-अभी पढ़ा कि using ब्लॉक अपवाद निगल। , foo2() और foo3() से foo() में अपवादों को संभालने का यह एक शानदार तरीका है। मैं विधियों में प्रत्येक using ब्लॉक के अंदर एक कोशिश/पकड़ना चाहता हूं। मैं this post में ठोकर खाई जहां एक विस्तार विधि का सुझाव दिया गया है, लेकिन मैं सिर्फ यह देखने के लिए जांच कर रहा हूं कि कुछ बेहतर है या नहीं।

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

धन्यवाद,

+7

क्या पृथ्वी पर आप के बारे में बात कर रहे हैं से बबल-अप और अपवाद के लिए इस कोड की कोशिश? प्रयोग अपवादों को अवरुद्ध नहीं करता है। यह इस अर्थ में अपवादों के साथ बातचीत करता है कि स्थानों का उपयोग करके एक निश्चित प्रयास .. मुख्य रूप से कथन ब्लॉक के आसपास है, लेकिन उपयोग कथन ब्लॉक के भीतर उठाए गए अपवादों को नहीं मारता है। – dthorpe

+2

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

+0

@ सेथो एमएसडीएन पेज बताता है कि कंपाइलर 'उपयोग' को 'try-end' ब्लॉक' में अनुवाद करता है, जहां 'आखिरकार' ब्लॉक कॉल 'डिस्प्ले()' है लेकिन कोई पकड़ ब्लॉक नहीं है, इसलिए किसी भी अपवाद को फेंक दिया जा सकता है। –

उत्तर

3

मुझे लगता है कि मैं भ्रम को समझता हूं। यहाँ कुछ छद्म कोड है (यह वास्तव में निष्पादित कर सकते हैं?) अधिक बस अपने परिदृश्य समझा:

public class Foo 
{ 
    public void DoStuff() 
    { 
     using (var x = new Thing()) 
     { 
      throw new ApplicationException("This code breaks"); 
     } 
    } 

    private class Thing : IDisposable 
    { 
     public override Dispose() 
     { 
      throw new ApplicationException("Help, I can't dispose!"); 
     } 
    } 
} 

इस कोड को इस कोड के रूप में ही रूप में सोचा जा सकता है:

public class Foo 
{ 
    public void DoStuff() 
    { 
     var x = new Thing(); 
     try 
     { 
      throw new ApplicationException("This code breaks"); 
      x.Dispose(); 
     } 
     catch (Exception err) 
     { 
      x.Dispose(); 
      rethrow; 
     } 
    } 

    private class Thing : IDisposable 
    { 
     public override Dispose() 
     { 
      throw new ApplicationException("Help, I can't dispose!"); 
     } 
    } 
} 

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

क्या यह समझ में आता है? क्या मैंने आपके प्रश्न का भी उत्तर दिया? मुझे यकीन नहीं है कि क्या आप इसे समझने में मदद की तलाश में हैं या क्या।

+1

क्या एक प्रयोग ब्लॉक में भी पकड़ है? मैंने सोचा कि यह सिर्फ एक कोशिश/आखिरकार था। –

+0

दरअसल मैं समझता हूं कि क्या हो रहा है। मेरे मामले में मैं 'SqlDataReader' का निपटान() का उपयोग कर रहा हूं, इसलिए कोई रीथ्रो या कोई अपवाद फेंक दिया गया है। मैं यह देखने की कोशिश कर रहा हूं कि कॉलर में विफलता का पता लगाने का कोई तरीका है या नहीं। –

+0

@ 0 ए0 डी: नहीं, लेकिन मैं इस बात पर बल देने के लिए थोड़ा वर्बोज़ रहा था कि इसे कैसे कार्य करना है। जब अंत में कोड निष्पादित करता है जो बदले में अपवाद फेंकता है, तो आपको अंततः ब्लॉक के कोड को निष्पादित करने के लिए यह नहीं मिलता है क्योंकि इसके माध्यम से एक अपवाद फेंक दिया जाता है। यह पोस्ट यह दिखाने के लिए नहीं था कि यह कौन सा कोड उत्पन्न करता है बल्कि यह दिखाने के लिए कि यह कैसे कार्य करता है और उस बिंदु पर जोर देता है। – Jaxidian

1

मेरा डर यह है कि माइक्रोसॉफ्ट ने उसी खरगोश छेद को नीचे चला गया जैसा उन्होंने डब्ल्यूसीएफ के साथ किया था।

Avoiding Problems with the Using Statement देखें।

शायद उन्हें अपने guidelines का पालन करना चाहिए।

लगभग हर (अन्य) मामले में using ब्लॉक एक सर्वोत्तम अभ्यास है।

0

Youcan एक का उपयोग कर बयान

Exception exc = null; 
using (var x = new object()) 
{ 
    try 
    { 
     // do something x, that causes an exception to be thrown 
    } 
    catch(Exception ex) { exc = ex; } // bubble-up the exception 
} 
if(exc != null) { throw exc; } // throw the exception if it is not null 
+0

यह ठीक काम करेगा, इस तथ्य को छोड़कर कि ऑब्जेक्ट IDISposable लागू नहीं करता है, और इस प्रकार इसका उपयोग नहीं किया जा सकता है एक प्रयोग कथन में, और इस फैशन में आपकी उथल-पुथल स्टैक ट्रेस को गड़बड़ कर देगी। –

+0

x = नई वस्तु(); आप सही वर्ग और पैरामीटर के साथ नई ऑब्जेक्ट() को प्रतिस्थापित कर सकते हैं। इसके अलावा, स्टैक ट्रेस बरकरार रहेगा ... क्योंकि आप शीर्ष-स्तरीय अपवाद के अनुसार स्टैक ट्रेस पढ़ सकते हैं या आंतरिक अपवाद की जांच कर सकते हैं। आप GetBaseException(), आदि को भी कॉल कर सकते हैं – NeoH4x0r

+0

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