क्या डिस्पोज़ को अभी भी बुलाया जाता है जब अपवाद का उपयोग करने वाले बयान के अंदर फेंक दिया जाता है?


103

नीचे दिए गए उदाहरण में, क्या कनेक्शन को बंद और निपटाया जा रहा है जब एक अपवाद को फेंक दिया जाता है अगर यह एक usingबयान के भीतर है ?

using (var conn = new SqlConnection("..."))
{
    conn.Open();
    // stuff happens here and exception is thrown...
}

मुझे पता है कि यह कोड नीचे यह सुनिश्चित कर देगा कि यह करता है, लेकिन मैं उत्सुक हूं कि स्टेटमेंट का उपयोग कैसे करता है।

var conn;
try
{
    conn = new SqlConnection("...");
    conn.Open();
    // stuff happens here and exception is thrown...
}
// catch it or let it bubble up
finally
{
    conn.Dispose();
}

सम्बंधित:

जब एक अपवाद को फेंक दिया जाता है तो SQL कनेक्शन बंद करने के लिए उचित तरीका क्या है?

जवाबों:


112

हां, usingएक कोशिश / अंत में अपने कोड को लपेटता है जहां मौजूद होने पर finallyभाग कॉल करेगा Dispose()। हालाँकि, Close()यह सीधे तौर पर कॉल नहीं करेगा क्योंकि यह केवल IDisposableइंटरफ़ेस लागू होने के लिए जाँच करता है और इसलिए Dispose()विधि है।

यह सभी देखें:


5
बस कनेक्शन वर्गों पर इंगित करने के लिए यदि आप उन पर परावर्तक करते हैं तो आप देखेंगे डिस्पोज़ () वास्तव में आंतरिक रूप से बंद () कहते हैं। यदि यह एक राज्य में है तो यह हो सकता है।
क्रिस मैरिसिक

2
आप सही हैं, यह करता है। हालाँकि, मैंने जानबूझ कर इसका उल्लेख नहीं किया क्योंकि मैं किसी को यह सोचने के लिए गुमराह नहीं करना चाहता था कि इसका आईडीसोफ्री या संबद्ध पैटर्न से कोई लेना-देना नहीं है। तथ्य यह है कि यह विशेष कार्यान्वयन बंद () को लागू करने का एक विवरण है, न कि पैटर्न।
जेफ़ येट्स

3
प्रलेखन का उपयोग करने वाला MSDN भी इस उत्तर की पुष्टि करता है: कथन का उपयोग यह सुनिश्चित करता है कि डिस्पोज़ को तब भी कहा जाता है, जब आप ऑब्जेक्ट पर कॉल करने के दौरान कोई अपवाद होते हैं। आप एक कोशिश ब्लॉक के अंदर वस्तु डालकर और फिर अंततः ब्लॉक में डिस्पोज को बुलाकर एक ही परिणाम प्राप्त कर सकते हैं; वास्तव में, यह है कि कंपाइलर द्वारा उपयोग किए गए कथन का अनुवाद कैसे किया जाता है।
ब्रॉडबैंड

20

इस तरह से परावर्तक आपके कोड द्वारा उत्पन्न IL को डिकोड करता है:

निजी स्थिर शून्य मुख्य (स्ट्रिंग [] args)
{
    SqlConnection con = नया SqlConnection ("...");
    प्रयत्न
    {
        conn.Open ();
        कार्य करना();
    }
    आखिरकार
    {
        अगर (कॉन! = null)
        {
            conn.Dispose ();
        }
    }
}

तो जवाब है हां, यह कनेक्शन बंद कर देगा अगर

कार्य करना()
एक अपवाद फेंकता है।


यदि con.Open जोड़ें () एक अपवाद फेंकता है। : D
जेफ

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

-1

डिस्पोज़ () इस कोड में नहीं मिलता है।

class Program {
    static void Main(string[] args) {
        using (SomeClass sc = new SomeClass())
        {
            string str = sc.DoSomething();
            sc.BlowUp();
        }
    }
}

public class SomeClass : IDisposable {
    private System.IO.StreamWriter wtr = null;

    public SomeClass() {
        string path = System.IO.Path.GetTempFileName();
        this.wtr = new System.IO.StreamWriter(path);
        this.wtr.WriteLine("SomeClass()");
    }

    public void BlowUp() {
        this.wtr.WriteLine("BlowUp()");
        throw new Exception("An exception was thrown.");
    }

    public string DoSomething() {
        this.wtr.WriteLine("DoSomething()");
        return "Did something.";
    }

    public void Dispose() {
        this.wtr.WriteLine("Dispose()");
        this.wtr.Dispose();
    }
}

क्या यह ओपी सवाल का जवाब देता है ??
जोए फिलिप्स

हाँ। जवाब न है। संलग्न कोड में डिस्पोज़ () नहीं मिलता है। इसके अलावा, जो अपवाद फेंका गया है, उसे संभाला नहीं जाता है और कार्यक्रम को गति मिलती है।
चाड

आप गलत फ़ाइल को देख रहे होंगे। "डिस्पोज़ ()" आपकी टेम्प फ़ाइल में लिखा जाता है। कोई भी दावा नहीं करता है कि एक उपयोग-ब्लॉक एक अपवाद को संभाल लेगा। इसे डिबगर के बिना चलाने का प्रयास करें।
लार्सटेक

मैंने यह ठीक उसी कोड को चलाया है और यह Dispose () कहता है। क्या आप सुनिश्चित हैं कि आपका उत्तर सही है?
प्रातः
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.