2011-01-17 8 views
114

पहला सवाल:
मैंएक एसक्यूएलकनेक्शन वापसी या अपवाद पर बंद है?

using (SqlConnection connection = new SqlConnection(connectionString)) 
{ 
    connection.Open(); 

    string storedProc = "GetData"; 
    SqlCommand command = new SqlCommand(storedProc, connection); 
    command.CommandType = CommandType.StoredProcedure; 
    command.Parameters.Add(new SqlParameter("@EmployeeID", employeeID)); 

    return (byte[])command.ExecuteScalar(); 
} 

कनेक्शन बंद कर दिया हो करता है कहो? क्योंकि तकनीकी रूप से हम कभी भी } तक नहीं पहुंचते हैं क्योंकि हम return इससे पहले।

दूसरा सवाल:
इस बार मेरे पास है:

try 
{ 
    using (SqlConnection connection = new SqlConnection(connectionString)) 
    { 
     int employeeID = findEmployeeID(); 

     connection.Open(); 
     SqlCommand command = new SqlCommand("UpdateEmployeeTable", connection); 
     command.CommandType = CommandType.StoredProcedure; 
     command.Parameters.Add(new SqlParameter("@EmployeeID", employeeID)); 
     command.CommandTimeout = 5; 

     command.ExecuteNonQuery(); 
    } 
} 
catch (Exception) { /*Handle error*/ } 

अब, try में कहीं कहते हैं कि हम कोई त्रुटि मिलती है और यह पकड़ा जाता है। क्या कनेक्शन अभी भी बंद हो जाता है? क्योंकि फिर से, हम शेष कोड को try में छोड़ देते हैं और सीधे catch कथन पर जाते हैं।

क्या मैं using काम करता हूं में बहुत रैखिक रूप से सोच रहा हूं? यानी Dispose() जब हम using गुंजाइश छोड़ते हैं तो बस कॉल किया जाता है?

उत्तर

148
  1. हाँ
  2. हां।

किसी भी तरह से, जब उपयोग ब्लॉक बाहर निकलता है (या तो सफल समापन या त्रुटि से) यह बंद हो जाता है।

हालांकि मुझे लगता है कि यह बेहतर इस तरह व्यवस्थित करने के लिए है क्योंकि यह एक बहुत आसान है यह देखने के लिए कि क्या होने वाला है हो सकता है, यहां तक ​​कि नई रखरखाव प्रोग्रामर जो बाद में इसे समर्थन करेंगे के लिए:

using (SqlConnection connection = new SqlConnection(connectionString)) 
{  
    int employeeID = findEmployeeID();  
    try  
    { 

      connection.Open(); 
      SqlCommand command = new SqlCommand("UpdateEmployeeTable", connection); 
      command.CommandType = CommandType.StoredProcedure; 
      command.Parameters.Add(new SqlParameter("@EmployeeID", employeeID)); 
      command.CommandTimeout = 5; 

      command.ExecuteNonQuery();  
    } 
    catch (Exception) 
    { 
     /*Handle error*/ 
    } 

} 
+2

@TreueWill - मैं सहमत हूं। मैंने बस ढांचे के लिए कोड को थोड़ा सा स्थानांतरित कर दिया। – David

+7

प्रश्न: क्या मुझे उपयोग कथन का उपयोग करते समय कनेक्शन खोलने की आवश्यकता है? – Fandango68

+3

यदि आप लेन-देन का उपयोग कर रहे हैं, तो 'उपयोग करने' के भीतर 'प्रयास करें' रखने के द्वारा आप 'पकड़' में स्पष्ट रूप से 'कॉमिट' या 'रोलबैक' लेनदेन कर सकते हैं। यह दोनों अधिक पठनीय और स्पष्ट है, और यदि आप अपवाद के प्रकार को समझते हैं तो आपको प्रतिबद्ध करने की अनुमति मिलती है। (यदि लेनदेन नहीं किया जाता है तो लेनदेन पूरी तरह से 'conn.close' पर वापस रोल करें।)। – Chris

2

अपने पहले उदाहरण में, सी # संकलक वास्तव में निम्न के कथन का उपयोग अनुवाद कर देगा:

SqlConnection connection = new SqlConnection(connectionString)); 

try 
{ 
    connection.Open(); 

    string storedProc = "GetData"; 
    SqlCommand command = new SqlCommand(storedProc, connection); 
    command.CommandType = CommandType.StoredProcedure; 
    command.Parameters.Add(new SqlParameter("@EmployeeID", employeeID)); 

    return (byte[])command.ExecuteScalar(); 
} 
finally 
{ 
    connection.Dispose(); 
} 

अंत में बयान हमेशा कहा जाता हो जाएगा से पहले एक फ़ंक्शन रिटर्न और इसलिए कनेक्शन हमेशा बंद/डिस्पोजेड किया जाएगा।

तो, अपने दूसरे उदाहरण में कोड का पालन करने के संकलित किया जाएगा:

try 
{ 
    try 
    { 
     connection.Open(); 

     string storedProc = "GetData"; 
     SqlCommand command = new SqlCommand(storedProc, connection); 
     command.CommandType = CommandType.StoredProcedure; 
     command.Parameters.Add(new SqlParameter("@EmployeeID", employeeID)); 

     return (byte[])command.ExecuteScalar(); 
    } 
    finally 
    { 
     connection.Dispose(); 
    } 
} 
catch (Exception) 
{ 
} 

अपवाद अंत में बयान में पकड़ा जाएगा और कनेक्शन बंद कर दिया। बाहरी पकड़ खंड द्वारा अपवाद नहीं देखा जाएगा।

+1

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

5

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

MSDN से

:

एक बयान का उपयोग कर या तो बाहर निकल गया जा सकता है जब कथन का उपयोग के अंत तक पहुँच जाता है या एक अपवाद फेंक दिया जाता है और नियंत्रण बयान के अंत से पहले बयान ब्लॉक छोड़ देता है।

4

Using उत्पन्न करता है एक कोशिश/अंत में वस्तु के आसपास आवंटित किया जा रहा है और आप के लिए Dispose() कहता है।

यह आप मैन्युअल रूप से बनाने की कोशिश/अंत में ब्लॉक और दोनों सवालों के Dispose()

39

हाँ बुला की परेशानी बचाता है। कथन का उपयोग एक कोशिश में संकलित किया जाता है/अंत में ब्लॉक

using (SqlConnection connection = new SqlConnection(connectionString)) 
{ 
} 

में ही है के रूप में

SqlConnection connection = null; 
try 
{ 
    connection = new SqlConnection(connectionString); 
} 
finally 
{ 
    if(connection != null) 
     ((IDisposable)connection).Dispose(); 
} 

संपादित करें: डिस्पोजेबल http://msdn.microsoft.com/en-us/library/yh598w02.aspx

+0

यह बिल्कुल ठीक नहीं है, लेकिन यह काफी करीब है। सटीक अंतर महत्वपूर्ण नहीं है। – Bryan

+0

@ ब्रायन को यह नहीं मिला, क्या आप सही अंतर का उल्लेख कर सकते हैं, हमें और अधिक दुबला करने में मदद कर सकते हैं :-) – mohits00691

+0

वाह, यह एक टिप्पणी बहुत समय पहले हुई थी :) ऐसा लगता है कि दिन के बाद एक संपादन हुआ था मैंने यह टिप्पणी की। मुझे लगता है कि वह अंतर है जिसके बारे में मैं सोच रहा था। – Bryan

11

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

string connString = System.Configuration.ConfigurationManager.ConnectionStrings["CompanyServer"].ConnectionString; 
string selectStatement = @" 
    SELECT TOP 1 Person 
    FROM CorporateOffice 
    WHERE HeadUpAss = 1 AND Title LIKE 'C-Level%' 
    ORDER BY IntelligenceQuotient DESC 
"; 
using (SqlConnection conn = new SqlConnection(connString)) 
{ 
    using (SqlCommand comm = new SqlCommand(selectStatement, conn)) 
    { 
     try 
     { 
      conn.Open(); 
      using (SqlDataReader dr = comm.ExecuteReader()) 
      { 
       if (dr.HasRows) 
       { 
        while (dr.Read()) 
        { 
         Console.WriteLine(dr["Person"].ToString()); 
        } 
       } 
       else Console.WriteLine("No C-Level with Head Up Ass Found!? (Very Odd)"); 
      } 
     } 
     catch (Exception e) { Console.WriteLine("Error: " + e.Message); } 
     if (conn.State == System.Data.ConnectionState.Open) conn.Close(); 
    } 
} 

* संशोधित: 2015/11/09 *
NickG द्वारा सुझाव दिया गया है; भी कई ब्रेसिज़ आप कष्टप्रद, इस तरह प्रारूप ...

using (SqlConnection conn = new SqlConnection(connString)) 
    using (SqlCommand comm = new SqlCommand(selectStatement, conn)) 
    { 
     try 
     { 
     conn.Open(); 
     using (SqlDataReader dr = comm.ExecuteReader()) 
      if (dr.HasRows) 
       while (dr.Read()) Console.WriteLine(dr["Person"].ToString()); 
      else Console.WriteLine("No C-Level with Head Up Ass Found!? (Very Odd)"); 
     } 
     catch (Exception e) { Console.WriteLine("Error: " + e.Message); } 
     if (conn.State == System.Data.ConnectionState.Open) conn.Close(); 
    } 
फिर

तब, यदि आप ईए या भोर खेल के लिए काम करते हैं, आप बस किसी भी लाइन ब्रेक छोड़ कर सकते हैं और साथ ही, क्योंकि उन लोगों के लिए बस कर रहे हैं कर रहे हैं, जो वापस आना और बाद में अपना कोड देखना है और वास्तव में कौन परवाह करता है? क्या मैं सही हू? मेरा मतलब है 23 की बजाय 1 लाइन का मतलब है कि मैं एक बेहतर प्रोग्रामर हूं, है ना?

using (SqlConnection conn = new SqlConnection(connString)) using (SqlCommand comm = new SqlCommand(selectStatement, conn)) { try { conn.Open(); using (SqlDataReader dr = comm.ExecuteReader()) if (dr.HasRows) while (dr.Read()) Console.WriteLine(dr["Person"].ToString()); else Console.WriteLine("No C-Level with Head Up Ass Found!? (Very Odd)"); } catch (Exception e) { Console.WriteLine("Error: " + e.Message); } if (conn.State == System.Data.ConnectionState.Open) conn.Close(); } 

पुhew ... ठीक है। मैंने इसे अपने सिस्टम से बाहर कर लिया और थोड़ी देर के लिए खुद को मनोरंजक कर दिया। लगे रहो।

+6

क्या आप जानते थे कि आप अतिरिक्त ब्रेसिज़ के बिना बयान का उपयोग कर ढेर कर सकते हैं? अंतिम ब्रेस हटाएं, फिर एक-दूसरे के बगल में उपयोग कथन रखें :) – NickG

+0

हां सर। धन्यवाद। मुझे पता है, लेकिन मेरा कोड यह दिखाना चाहता था कि बहुत सारे छोटे कटौती के बिना क्या हो रहा था। हालांकि अंतिम पाठकों को जोड़ने के लिए अच्छा नोट। – ShaneLS

+0

आप अंत में 'conn.Close();' का उपयोग क्यों करते हैं? क्या 'स्टेटमेंट' का उपयोग नहीं करना आपके लिए निपटान के माध्यम से करता है? –

0

मैं एक ट्राई/कैच ब्लॉक के अंदर बयानों का उपयोग कर दो लिखा था और मैं देख सकता अपवाद उसी तरह पकड़ा जा रहा था अगर यह भीतरी कथन का उपयोग सिर्फ ShaneLS example के रूप में रखा गया है।

 try 
    { 
     using (var con = new SqlConnection(@"Data Source=...")) 
     { 
     var cad = "INSERT INTO table VALUES (@r1,@r2,@r3)"; 

     using (var insertCommand = new SqlCommand(cad, con)) 
     { 
      insertCommand.Parameters.AddWithValue("@r1", atxt); 
      insertCommand.Parameters.AddWithValue("@r2", btxt); 
      insertCommand.Parameters.AddWithValue("@r3", ctxt); 
      con.Open(); 
      insertCommand.ExecuteNonQuery(); 
     } 
     } 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show("Error: " + ex.Message, "UsingTest", MessageBoxButtons.OK, MessageBoxIcon.Error); 
    } 

चाहे कहीं ट्राई/कैच रखा है, अपवाद के मुद्दों के बिना पकड़ा दिया जाएगा।

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