2008-09-26 14 views
18

मैं ऐसे पैटर्न का उपयोग करता हूं जो इस तरह कुछ दिखता है। मैं सोच रहा हूं कि यह ठीक है या यदि कोई सर्वोत्तम अभ्यास है कि मैं यहां आवेदन नहीं कर रहा हूं।अपवाद फेंकने पर SQL कनेक्शन बंद होने का यह सुनिश्चित करने का उचित तरीका क्या है?

विशेष रूप से मैं सोच रहा हूं; इस मामले में कि एक अपवाद फेंक दिया गया है वह कोड है जो आखिरकार ब्लॉक में पर्याप्त है, यह सुनिश्चित करने के लिए कि कनेक्शन उचित रूप से बंद है?

public class SomeDataClass : IDisposable 
{ 
    private SqlConnection _conn; 

    //constructors and methods 

    private DoSomethingWithTheSqlConnection() 
    { 
     //some code excluded for brevity 

     try 
     { 
      using (SqlCommand cmd = new SqlCommand(SqlQuery.CountSomething, _SqlConnection)) 
      { 
       _SqlConnection.Open(); 
       countOfSomething = Convert.ToInt32(cmd.ExecuteScalar()); 
      } 
     } 
     finally 
     { 
      //is this the best way? 
      if (_SqlConnection.State == ConnectionState.Closed) 
       _SqlConnection.Close(); 
     } 

     //some code excluded for brevity 
    } 

    public Dispose() 
    { 
     _conn.Dispose(); 
    } 
} 
+1

उह ... तुम क्यों की जाँच कर रहे है कि कनेक्शन पहले से ही बंद करने से पहले बंद कर दिया है? और कनेक्शन को स्टोर करने के लिए क्लास सदस्य का उपयोग क्यों करें, यदि आप इसका उपयोग कर एकमात्र विधि में बंद कर रहे हैं? – Shog9

+1

spoon16 वाक्यांश "// कुछ कोड संक्षिप्तता के लिए बाहर रखा गया" वाक्यांश शामिल था। इससे, मैं अनुमान लगाता हूं कि इसका उपयोग करने का यह एकमात्र तरीका नहीं है। –

+0

सही, यह बिल्कुल सरल उदाहरण है जिसे मैं सोच सकता हूं। मुझे लगता है कि कनेक्शन पूलिंग के कारण मुझे प्रत्येक विधि के दायरे के बाहर एक एसक्यूएलकनेक्शन ऑब्जेक्ट को स्टोर करने की आवश्यकता नहीं है। तो बस अन्य अनुशंसित के रूप में उपयोग करने के लिए उपयोग करने जा रहा है। –

उत्तर

45

आप IDisposables वैसे भी प्रयोग कर रहे हैं के बाद से एक

using (SqlConnection conn = new SqlConnection (...)) 
{ 
    // Whatever happens in here, the connection is 
    // disposed of (closed) at the end. 
} 
+0

यह भी ध्यान रखें कि जब तक आप इसे विशेष रूप से कनेक्शन स्ट्रिंग में बंद नहीं करते हैं, तो .NET पूल डिफ़ॉल्ट रूप से कनेक्शन करता है, इसलिए आपको इसे पुन: उपयोग करने के लिए कनेक्शन पर लटकने की आवश्यकता नहीं है। –

1

"का उपयोग" अंदर अपने डेटाबेस से निपटने कोड लपेटें। आप 'उपयोग' कीवर्ड का उपयोग कर सकते हैं, जो मूल रूप से आखिरकार ब्लॉक में निपटने के बराबर है, लेकिन यह बेहतर दिखता है।

2

मैं अनुमान लगा रहा हूं कि "_SqlConnection.State == कनेक्शन स्तर। बंद" आपका मतलब है! =।

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

एक चीज जिसे आपको निश्चित रूप से बदलना चाहिए, हालांकि, निपटान() विधि है। आपको निपटान में कनेक्शन ऑब्जेक्ट का संदर्भ नहीं देना चाहिए, क्योंकि उस बिंदु पर इसे पहले से ही अंतिम रूप दिया जा सकता है। आपको इसके बजाय अनुशंसित निपटान पैटर्न का पालन करना चाहिए।


    class SqlOpener : IDisposable 
    { 
     SqlConnection _connection; 

     public SqlOpener(SqlConnection connection) 
     { 
      _connection = connection; 
      _connection.Open(); 

     } 

     void IDisposable.Dispose() 
     { 
      _connection.Close(); 
     } 
    } 

    public class SomeDataClass : IDisposable 
    { 
     private SqlConnection _conn; 

     //constructors and methods 

     private void DoSomethingWithTheSqlConnection() 
     { 
      //some code excluded for brevity 
      using (SqlCommand cmd = new SqlCommand("some sql query", _conn)) 
      using(new SqlOpener(_conn)) 
      { 
       int countOfSomething = Convert.ToInt32(cmd.ExecuteScalar()); 
      } 
      //some code excluded for brevity 
     } 

     public void Dispose() 
     { 
      _conn.Dispose(); 
     } 
    } 

आशा में मदद करता है :)

-4

मैं इस सुझाव दे सकता है। अंत में अपवाद फेंकने से पहले ब्लॉक को निष्पादित किया जाता है। एक "प्रयोग" ब्लॉक का उपयोग करना भी काम करता है, लेकिन मुझे स्पष्ट "अंत" विधि अधिक स्पष्ट मिलती है।

कथन का उपयोग कई डेवलपर्स के लिए पुरानी टोपी है, लेकिन युवा डेवलपर्स शायद हाथ से नहीं जानते हैं।

+0

-1: काम नहीं करता है! SqlCommand अभी भी एक शून्य संदर्भ आयोजित कर रहा है। कृपया इसे ठीक न करें - – Joe

+0

एआरआर के ऊपर मानक समाधान के साथ चिपके रहें, वास्तव में मुझे यह मानने में कोई समस्या नहीं है कि कोड * लगभग * यह वास्तव में कनेक्शन बनाता है। देखें, अगर "_conn" ठीक तरह से प्रारंभ नहीं किया गया है तो यह काम नहीं करेगा। –

1

एक "अंत में" ब्लॉक के अंदर कनेक्शन करीब कोड रखो की तरह आपको बताएंगे:

+0

"उपयोग" कथन किसी भी व्यक्ति के लिए बहुत स्पष्ट है जो सी # से परिचित है।मैं इस समय पेशेवर रूप से जावा का उपयोग कर रहा हूं, और "उपयोग" के साथ प्रयास/अंत में अतिरिक्त सामान एक असली कोर है। "उपयोग" कथन सी # में संसाधन हैंडलिंग का बेवकूफ माध्यम है। –

+0

पर्याप्त मेला, लेकिन मुझे लगता है कि जब भी मुझे पता है कि "उपयोग" की तरह कुछ क्या है, वास्तव में कोड को देखने से मुझे कार्रवाई को देखने में मदद मिलती है। इसके अलावा मैं अकेला नहीं हूं जो मेरा कोड देख रहा है। –

8

नेट फ्रेमवर्क किसी कारण के लिए कनेक्शन पूल रखता है। विशवास करो! :) आपको डेटाबेस से कनेक्ट करने और कनेक्शन को छोड़ने के लिए बस इतना कोड लिखना नहीं है।

आप केवल 'उपयोग' कथन का उपयोग कर सकते हैं और बाकी आश्वासन दिया है कि 'IDBConnection.Release()' आपके लिए कनेक्शन बंद कर देगा।

अत्यधिक विस्तृत 'समाधान' परिणामस्वरूप बग्गी कोड में होते हैं। सरल बेहतर है।

5

MSDN Docs इस सुंदर स्पष्ट कर दूं ...

  • बंद विधि वापस रोल किसी भी लेन-देन लंबित। यह कनेक्शन कनेक्शन से कनेक्शन जारी करता है, या कनेक्शन पूलिंग अक्षम होने पर कनेक्शन बंद कर देता है।

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


  • एक आवेदन बंद एक से अधिक समय फोन कर सकते हैं। कोई अपवाद उत्पन्न नहीं होता है।

तो बंद होने के लिए परीक्षण परेशान क्यों करें? बस बंद करें()।


  • बंद और निपटान कार्यात्मक रूप से बराबर कर रहे हैं।

यही कारण है कि ब्लॉक कनेक्शन का उपयोग बंद कनेक्शन में होता है। कॉल का उपयोग करके आप के लिए निपटान करें।


  • बंद कॉल या एक कनेक्शन, किसी DataReader या अपनी कक्षा के अंतिम रूप विधि में किसी भी अन्य प्रबंधित वस्तु पर फेंक नहीं है।

महत्वपूर्ण सुरक्षा युक्ति। धन्यवाद, एगॉन।

1

जवाब के लिए इस सवाल का देखें: आपके कनेक्शन की जीवन भर एक भी विधि कॉल है

Close and Dispose - which to call?

, तो कनेक्शन के समुचित सफाई सुनिश्चित करने के लिए भाषा का using सुविधा का उपयोग। जबकि try/finally ब्लॉक कार्यात्मक रूप से वही है, इसके लिए अधिक कोड की आवश्यकता है और आईएमओ कम पठनीय है। कनेक्शन की स्थिति की जांच करने की कोई आवश्यकता नहीं है, आप Dispose पर ध्यान दिए बिना कॉल कर सकते हैं और यह कनेक्शन को सफाई-संभाल लेगा।

यदि आपका कनेक्शन जीवनकाल किसी विशेष श्रेणी के जीवनकाल से मेल खाता है, तो IDisposable लागू करें और Dispose में कनेक्शन को साफ़ करें।

0

एक try..finally की कोई जरूरत के चारों ओर एक "का उपयोग", का उपयोग कर है एक try..finally

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

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