2008-10-30 17 views
28

मैं सिर्फ कथन का उपयोग से देख रहा हूँ, मैं हमेशा से जानते हैं कि वह क्या करता है, लेकिन अब तक यह उपयोग करने की कोशिश नहीं, मैं नीचे दिए गए कोड के साथ आए हैं:सी # कथन का उपयोग पकड़ त्रुटि

using (SqlCommand cmd = 
    new SqlCommand(reportDataSource, 
     new SqlConnection(Settings.Default.qlsdat_extensionsConnectionString))) 
{ 
    cmd.CommandType = CommandType.StoredProcedure; 
    cmd.Parameters.Add("@Year", SqlDbType.Char, 4).Value = year; 
    cmd.Parameters.Add("@startDate", SqlDbType.DateTime).Value = start; 
    cmd.Parameters.Add("@endDate", SqlDbType.DateTime).Value = end; 
    cmd.Connection.Open(); 

    DataSet dset = new DataSet(); 
    new SqlDataAdapter(cmd).Fill(dset); 
    this.gridDataSource.DataSource = dset.Tables[0]; 
} 

यह लगता है काम करने के लिए, लेकिन इसमें कोई मुद्दा है, जहां तक ​​मैं कह सकता हूं कि मुझे अभी भी असुरक्षित त्रुटियों को पकड़ने के लिए कोशिश करने के लिए प्रयास ब्लॉक में संलग्न करने की आवश्यकता होगी। एसक्यूएल सर्वर नीचे। क्या मैं कुछ भूल रहा हूँ?

जहां तक ​​मैं वर्तमान में इसे देख सकता हूं बस मुझे बंद कर देता है और cmd का निपटान बंद कर देता है लेकिन अभी भी कोशिश की जा रही कोशिश के कारण कोड की अधिक लाइनें होंगी।

उत्तर

18

यह कोड कनेक्शन के समय पर बंद होने सुनिश्चित करने के लिए निम्नानुसार होना चाहिए। बस आदेश समापन कनेक्शन बंद नहीं करता है:

using (SqlConnection con = new SqlConnection(Settings.Default.qlsdat_extensionsConnectionString)) 
using (SqlCommand cmd = new SqlCommand(reportDataSource, con)) 
     { 
      cmd.CommandType = CommandType.StoredProcedure; 
      cmd.Parameters.Add("@Year", SqlDbType.Char, 4).Value = year; 
      cmd.Parameters.Add("@startDate", SqlDbType.DateTime).Value = start; 
      cmd.Parameters.Add("@endDate", SqlDbType.DateTime).Value = end; 
      cmd.Connection.Open(); 

      DataSet dset = new DataSet(); 
      new SqlDataAdapter(cmd).Fill(dset); 
      this.gridDataSource.DataSource = dset.Tables[0]; 
     } 

आपके प्रश्न का उत्तर करने के लिए, आप एक अंत में ब्लॉक में भी ऐसा ही कर सकते हैं, लेकिन यह अच्छी तरह से कोड scopes और आप को साफ करने के लिए याद है कि सुनिश्चित करता है।

+2

आपने डीबी कनेक्शन के साथ असुरक्षित त्रुटियों को पकड़ने के बारे में कुछ भी नहीं बताया ... –

4

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

+2

मैं देख रहा हूं कि आपकी कहानियां क्या है, लेकिन आखिरकार बंद करने और बयान के निपटारे के साथ प्रयास करने के लिए मुझे एक प्रयास पर लाभ नहीं दिख रहा है। – PeteT

+2

संसाधन कचरा कलेक्टर के दृश्य से बाहर नहीं हो सकते हैं। जीसी के इंतजार के बजाय उन्हें एएसएपी को साफ करना अभी भी सहायक है। –

+1

यह कचरा कलेक्टर के बारे में नहीं है, या तो। –

2

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

यह बिल्कुल बिल्कुल जरूरी नहीं है, लेकिन यह आपके कोड का उपयोग करके किसी और को अपना इरादा परिभाषित करता है , और यह गलती से खोलने वाले कनेक्शन आदि को छोड़ने में भी मदद करता है।

57

आईओ काम करते समय मैं पर कोड एक अपवाद की उम्मीद करता हूं।

SqlConnection conn = null; 
SqlCommand cmd = null; 

try 
{ 
    conn = new SqlConnection(Settings.Default.qlsdat_extensionsConnectionString) 
    cmd = new SqlCommand(reportDataSource, conn); 
    cmd.CommandType = CommandType.StoredProcedure; 
    cmd.Parameters.Add("@Year", SqlDbType.Char, 4).Value = year; 
    cmd.Parameters.Add("@startDate", SqlDbType.DateTime).Value = start; 
    cmd.Parameters.Add("@endDate", SqlDbType.DateTime).Value = end; 

     conn.Open(); //opens connection 

    DataSet dset = new DataSet(); 
    new SqlDataAdapter(cmd).Fill(dset); 
    this.gridDataSource.DataSource = dset.Tables[0]; 
} 
catch(Exception ex) 
{ 
    Logger.Log(ex); 
    throw; 
} 
finally 
{ 
    if(conn != null) 
     conn.Dispose(); 

     if(cmd != null) 
     cmd.Dispose(); 
} 

संपादित करें: स्पष्ट होना करने के लिए, मैं ब्लॉक यहाँ का उपयोग कर, क्योंकि मेरा मानना ​​है कि यह इस तरह की स्थितियों में लॉग इन करने के लिए महत्वपूर्ण होने के लिए करने से बचें। अनुभव ने मुझे सिखाया है कि आप कभी नहीं जानते कि किस तरह का अजीब अपवाद पॉप अप हो सकता है। इस स्थिति में लॉग इन करने से आप डेडलॉक का पता लगाने में मदद कर सकते हैं, या यह पता लगा सकते हैं कि स्कीमा परिवर्तन आपके कोड बेस के छोटे इस्तेमाल और छोटे परीक्षण वाले हिस्से को प्रभावित कर रहा है, या अन्य समस्याओं की संख्या।

संपादित करें 2: कोई तर्क दे सकता है कि एक उपयोग ब्लॉक इस स्थिति में कोशिश/पकड़ लपेट सकता है, और यह पूरी तरह से वैध और कार्यात्मक रूप से समकक्ष है। यह वास्तव में वरीयता के लिए उबाल जाता है। क्या आप अपने निपटान को संभालने की लागत पर अतिरिक्त घोंसले से बचना चाहते हैं? या आप ऑटो-निपटान करने के लिए अतिरिक्त घोंसले लगते हैं। मुझे लगता है कि पूर्व क्लीनर है इसलिए मैं इसे इस तरह से करता हूं। हालांकि, अगर मैं इसे कोड बेस में ढूंढता हूं जिसमें मैं काम कर रहा हूं, तो मैं बाद वाले को फिर से लिख नहीं सकता।

संपादित करें 3: मैं वास्तव में चाहता हूं कि एमएस ने() का उपयोग करने के एक और स्पष्ट संस्करण को बनाया है (जिसने इसे वास्तव में और अधिक सहज ज्ञान दिया और इस मामले में अधिक लचीलापन दिया। निम्नलिखित, काल्पनिक कोड पर विचार करें:

SqlConnection conn = null; 
SqlCommand cmd = null; 

using(conn = new SqlConnection(Settings.Default.qlsdat_extensionsConnectionString), 
      cmd = new SqlCommand(reportDataSource, conn) 
{ 
    conn = new SqlConnection(Settings.Default.qlsdat_extensionsConnectionString); 
    cmd = new SqlCommand(reportDataSource, conn); 
    cmd.CommandType = CommandType.StoredProcedure; 
    cmd.Parameters.Add("@Year", SqlDbType.Char, 4).Value = year; 
    cmd.Parameters.Add("@startDate", SqlDbType.DateTime).Value = start; 
    cmd.Parameters.Add("@endDate", SqlDbType.DateTime).Value = end; 
     cmd.Open(); 

    DataSet dset = new DataSet(); 
    new SqlDataAdapter(cmd).Fill(dset); 
    this.gridDataSource.DataSource = dset.Tables[0]; 
} 
catch(Exception ex) 
{ 
    Logger.Log(ex); 
    throw; 
} 

एक उपयोग कथन बस अंततः निपटान() कॉल के साथ प्रयास/अंत में बनाता है। डेवलपर को निपटान और अपवाद हैंडलिंग करने का एक एकीकृत तरीका क्यों न दें?

+0

क्यों स्पष्ट निपटान, जब उपयोग ब्लॉक एक ही चीज़ को और अधिक सुंदरता से करता है? – yfeldblum

+3

तो मैं अपवाद लॉग कर सकता हूं। देश/दुनिया के एक दूरस्थ भाग में किसी उपयोगकर्ता के डेस्कटॉप पर रनटाइम अपवाद में कुछ भी सुरुचिपूर्ण नहीं है, और आपके पास कोई संकेत नहीं है कि क्या गलत हुआ। –

+3

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

1

उपयोग कथन वास्तव में संकलक द्वारा कोशिश/आखिरकार ब्लॉक में बदल दिया गया है जिसमें उपयोग ब्लॉक के पैरामीटर को तब तक निपटाया जाता है जब यह आईडीस्पोजेबल इंटरफ़ेस लागू करता है। विनिर्देशों को सुनिश्चित करने के अलावा, जब वे दायरे से बाहर निकलते हैं तो सही ढंग से निपटान किया जाता है, इस निर्माण का उपयोग करके वास्तव में कोई त्रुटि कैप्चरिंग नहीं होती है।

जैसा कि उपरोक्त सॉफ्टवेयर Jedi द्वारा उल्लिखित है, आप यह सुनिश्चित करना चाहते हैं कि SqlConnection और SqlCommand ऑब्जेक्ट्स दोनों का ठीक से निपटान किया गया हो। ब्लॉक का उपयोग करके एकल में दोनों को ढेर करना थोड़ा गन्दा है, और ऐसा नहीं हो सकता है जो आपको लगता है कि यह करता है।

इसके अलावा, तर्क के रूप में प्रयास/पकड़ ब्लॉक का उपयोग करने के लिए सावधान रहें। यह एक कोड गंध है कि मेरी नाक के लिए विशेष रूप से नापसंद है, और अक्सर समय सीमा को पूरा करने के लिए नए लोगों या हमारे द्वारा उपयोग किए जाने वाले लोगों द्वारा उपयोग किया जाता है।

1

FYI, इस विशिष्ट उदाहरण में, क्योंकि आप एक ADO.net कनेक्शन और कमांड ऑब्जेक्ट का उपयोग कर रहे हैं, इस बात से अवगत रहें कि उपयोग कथन केवल कमांड निष्पादित करता है। व्यवहार करें, और कनेक्शन। Disispose() जो वास्तव में बंद नहीं होता कनेक्शन, लेकिन इसे वापस अगले कनेक्शन द्वारा पुन: उपयोग करने के लिए ADO.net कनेक्शन पूल में रिलीज़ करता है। ओपन ... जो अच्छा है, और करने के लिए बिल्कुल सही चीज है, बीसी अगर आप नहीं करते हैं, कनेक्शन रहेगा अनुपयोगी जब तक कचरा कलेक्टर इसे वापस पूल में रिलीज़ नहीं करता है, जो कई अन्य कनेक्शन अनुरोधों तक नहीं हो सकता है, जो अन्यथा नए कनेक्शन बनाने के लिए मजबूर होना पड़ता है, भले ही एक अप्रयुक्त व्यक्ति कचरा होने का इंतजार कर रहा हो।

5

क्रिस बैलेंस ने क्या बताया, सी # विनिर्देश (ईसीएमए -334 संस्करण 4) खंड 15.13 कहता है "एक उपयोग कथन का तीन भागों में अनुवाद किया जाता है: अधिग्रहण, उपयोग, और निपटान। संसाधन का उपयोग पूरी तरह से संलग्न है आखिरी खंड शामिल है जिसमें अंततः खंड शामिल है। अंत में खंड संसाधन का निपटान करता है। यदि कोई शून्य संसाधन प्राप्त होता है, तो निपटान करने के लिए कोई कॉल नहीं किया जाता है, और कोई अपवाद नहीं फेंक दिया जाता है। "

विवरण 2 पृष्ठों के करीब है - पढ़ने के लायक है।

मेरे अनुभव में, SqlConnection/SqlCommand त्रुटियों को उत्पन्न कर सकता है ताकि आपको अपेक्षित व्यवहार को संभालने के अलावा लगभग अपवादों को संभालने की आवश्यकता हो। मुझे यकीन नहीं है कि मैं यहां उपयोग खंड चाहता हूं, क्योंकि मैं खुद को शून्य संसाधन केस को संभालने में सक्षम होना चाहता हूं।

2

यहां बहुत सारे अच्छे उत्तर हैं, लेकिन मुझे नहीं लगता कि यह अभी तक कहा गया है।

कोई फर्क नहीं पड़ता कि ... "निपटान" विधि को "उपयोग" ब्लॉक में ऑब्जेक्ट पर कॉल किया जाएगा। यदि आप एक वापसी कथन डालते हैं, या एक त्रुटि फेंक देते हैं, तो "निपटान" कहा जाएगा।

उदाहरण:

मैं एक वर्ग "MyDisposable" कहा जाता है बनाया है, और यह IDisposable लागू करता है और बस एक Console.Write करता है। अपने कोड इस तरह दिखता है, तो

using (MyDisposable blah = new MyDisposable()) 
{ 
    int.Parse("!"); // <- calls "Dispose" after the error. 

    return; // <-- calls Dispose before returning. 
} 
6

:

using (SqlCommand cmd = new SqlCommand(...)) 
{ 
    try 
    { 
    /* call stored procedure */ 
    } 
    catch (SqlException ex) 
    { 
    /* handles the exception. does not rethrow the exception */ 
    } 
} 

तो मैं .. पकड़ की कोशिश उपयोग करने के लिए यह refactor होगा .. अंत में के बजाय यह हमेशा कंसोल के लिए इन सभी स्थितियों में भी लिखते हैं ।

SqlCommand cmd = new SqlCommand(...) 
try 
{ 
    /* call stored procedure */ 
} 
catch (SqlException ex) 
{ 
    /* handles the exception and does not ignore it */ 
} 
finally 
{ 
    if (cmd!=null) cmd.Dispose(); 
} 

इस परिदृश्य में, मैं अपवाद को संभालने वाला होगा इसलिए मेरे पास उस प्रयास में जोड़ने के अलावा कोई विकल्प नहीं है ..पकड़ो, मैं अंत में खंड में डाल सकता हूं और खुद को एक और घोंसला स्तर बचा सकता हूं। ध्यान दें कि मुझे पकड़ ब्लॉक में कुछ करना होगा और अपवाद को अनदेखा नहीं करना चाहिए।

0

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

यह आपको परत/असेंबली सीमाओं पर अपवाद हैंडलिंग कोड रखने की अनुमति देता है और अन्य कार्यों को बहुत अव्यवस्थित होने में मदद करता है।

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

14

वहाँ इस मामले में एक using कथन का उपयोग करता है, तो क्या आप फिर भी एक try/catch/finally ब्लॉक करने जा रहे हैं करने के लिए कोई लाभ हो सकता है। जैसा कि आप जानते हैं, using कथन try/finally के लिए वाक्य रचनात्मक चीनी है जो IDisposable ऑब्जेक्ट का निपटान करता है। यदि आपके पास अपना खुद का try/finally है, तो आप निश्चित रूप से Dispose स्वयं कर सकते हैं।

यह वास्तव में मुख्य रूप से शैली में उबाल जाता है - आपकी टीम using कथन या using कथन के साथ अधिक आरामदायक हो सकती है, कथन कोड को क्लीनर बना सकता है।

लेकिन, यदि बॉयलरप्लेट using कथन छुपा रहेगा तो वैसे भी आगे बढ़ेगा, आगे बढ़ें और यदि आपकी वरीयता है तो चीजों को स्वयं संभालें।

0

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

+1

नहीं, एक "कोशिश/अंत" कथन के लिए वाक्य रचनात्मक चीनी है। जब तक आप कथन को एक और कोशिश/पकड़ या घोंसला में लपेट नहीं लेते, तब तक आप फेंकने वाले किसी भी अपवाद को नहीं पकड़ सकते; अप्रबंधित संसाधनों के साथ बातचीत करते समय मुझे कुछ जोखिम भरा लगता है। –

+0

यह सच नहीं है, कोशिश/पकड़/आखिरकार बदलने के लिए फैंसी तरीका नहीं है, क्योंकि यह आपको अपवादों को "पकड़ने" का तरीका प्रदान नहीं करता है। == कोशिश करें/अंत में (पकड़ के बिना)। यदि आपको अभी भी अपवाद पकड़ने और कुछ कस्टम प्रसंस्करण करने की आवश्यकता है, तो आपको कोशिश/पकड़ ब्लॉक के साथ उपयोग को लपेटना/घोंसला करना होगा, या इसे पूरी तरह से प्रयास/पकड़/अंत में बदलना होगा। – devfreak

0

माइनर सुधार: SqlDataAdapter भी एक using बयान में instantiated होने की जरूरत है: "का उपयोग कर" के साथ

using (SqlConnection con = new SqlConnection(Settings.Default.qlsdat_extensionsConnectionString)) 
using (SqlCommand cmd = new SqlCommand(reportDataSource, con)) 
{ 
    cmd.CommandType = CommandType.StoredProcedure; 
    cmd.Parameters.Add("@Year", SqlDbType.Char, 4).Value = year; 
    cmd.Parameters.Add("@startDate", SqlDbType.DateTime).Value = start; 
    cmd.Parameters.Add("@endDate", SqlDbType.DateTime).Value = end; 
    con.Open(); 

    DataSet dset = new DataSet(); 
    using (SqlDataAdapter adapter = new SqlDataAdapter(cmd)) 
    { 
     adapter.Fill(dset); 
    } 
    this.gridDataSource.DataSource = dset.Tables[0]; 
} 
4

एक मुद्दा यह है कि यह अपवाद हैंडल नहीं करता है। अगर "का उपयोग" "पकड़" स्यूडोकोड नीचे की तरह अपने वाक्यविन्यास बढ़ेगी वैकल्पिक रूप से डिजाइनर, यह बहुत अधिक उपयोगी होगा:

using (...MyDisposableObj...) 
{ 

    ... use MyDisposableObj ... 

catch (exception) 

    ... handle exception ... 

} 

it could even have an optional "finally" clause to cleanup anything other than the "MyDisposableObj" allocated at the beginning of the "using" statement... like: 

using (...MyDisposableObj...) 
{ 

    ... use MyDisposableObj ... 
    ... open a file or db connection ... 

catch (exception) 

    ... handle exception ... 

finally 

    ... close the file or db connection ... 

} 

अभी भी वहाँ MyDisposableObj ख के निपटान के लिए कोड लिखने की कोई जरूरत नहीं होगी/c इसे using द्वारा संभाला जाएगा ...

ऐसा कैसा लगता है?

1

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

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

0

पहले, अपने कोड उदाहरण होना चाहिए:

using (SqlConnection conn = new SqlConnection(Settings.Default.qlsdat_extensionsConnectionString)) 
using (SqlCommand cmd = new SqlCommand(reportDataSource, conn)) 
{ 
    cmd.CommandType = CommandType.StoredProcedure; 
    cmd.Parameters.Add("@Year", SqlDbType.Char, 4).Value = year; 
    cmd.Parameters.Add("@startDate", SqlDbType.DateTime).Value = start; 
    cmd.Parameters.Add("@endDate", SqlDbType.DateTime).Value = end; 
    cmd.Connection.Open(); 

    DataSet dset = new DataSet(); 
    new SqlDataAdapter(cmd).Fill(dset); 
    this.gridDataSource.DataSource = dset.Tables[0]; 
} 
अपने प्रश्न में कोड के साथ

, एक अपवाद आदेश बनाने सिर्फ रूप से बनाए गए संबंध में परिणाम होगा नहीं निपटाया जा रहा है। उपरोक्त के साथ, कनेक्शन ठीक से निपटान किया जाता है।

try 
{ 
    using (SqlConnection conn = new SqlConnection(Settings.Default.qlsdat_extensionsConnectionString)) 
    using (SqlCommand cmd = new SqlCommand(reportDataSource, conn)) 
    { 
     cmd.CommandType = CommandType.StoredProcedure; 
     cmd.Parameters.Add("@Year", SqlDbType.Char, 4).Value = year; 
     cmd.Parameters.Add("@startDate", SqlDbType.DateTime).Value = start; 
     cmd.Parameters.Add("@endDate", SqlDbType.DateTime).Value = end; 
     cmd.Connection.Open(); 

     DataSet dset = new DataSet(); 
     new SqlDataAdapter(cmd).Fill(dset); 
     this.gridDataSource.DataSource = dset.Tables[0]; 
    } 
} 
catch (RelevantException ex) 
{ 
    // ...handling... 
} 

:

आप (जब उन्हें प्रयोग के रूप में भी) निर्माण कनेक्शन और कमान की में अपवाद को संभालने के लिए की जरूरत है, हाँ, आप आज़माएं/कैच में पूरे बात रैप करने के लिए है लेकिन आपको conn या cmd की सफाई को संभालने की आवश्यकता नहीं है; यह आपके लिए पहले से ही किया जा चुका है। using बिना एक ही बात के साथ

कंट्रास्ट:

SqlConnection conn = null; 
SqlCommand cmd = null; 
try 
{ 
    conn = new SqlConnection(Settings.Default.qlsdat_extensionsConnectionString); 
    cmd = new SqlCommand(reportDataSource, conn); 
    cmd.CommandType = CommandType.StoredProcedure; 
    cmd.Parameters.Add("@Year", SqlDbType.Char, 4).Value = year; 
    cmd.Parameters.Add("@startDate", SqlDbType.DateTime).Value = start; 
    cmd.Parameters.Add("@endDate", SqlDbType.DateTime).Value = end; 
    cmd.Connection.Open(); 

    DataSet dset = new DataSet(); 
    new SqlDataAdapter(cmd).Fill(dset); 
    this.gridDataSource.DataSource = dset.Tables[0]; 
} 
catch (RelevantException ex) 
{ 
    // ...handling... 
} 
finally 
{ 
    if (cmd != null) 
    { 
     try 
     { 
      cmd.Dispose(); 
     } 
     catch { } 
     cmd = null; 
    } 
    if (conn != null) 
    { 
     try 
     { 
      conn.Dispose(); 
     } 
     catch { } 
     conn = null; 
    } 
} 
// And note that `cmd` and `conn` are still in scope here, even though they're useless 

मैं जानता हूँ कि जो मैं नहीं बल्कि लिखना चाहते हैं। :-)

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