[英]using statement with connection.open
我正在查看一些代碼並與同事討論。
特別是一段看起來像這樣的代碼。
[Test]
public void TestNormalWay()
{
using(var cn = GetConnection())
{
cn.Open();
// do stuff
}
}
問題出現了:
“為什么不將cn.Open移動到GetConnection方法中。”
我說如果“打開”拋出一個異常處理就不會被調用。 他的回答是
“那么什么。連接沒有打開,為什么需要關閉(或處理)?”
對我來說,這只是一個不想知道我是否需要處理/關閉的問題所以我會重復cn.Open代碼而不是將其移動到共享函數中。
但它很有趣......所以我在SQL Server連接池(ADO.NET)上做了一些閱讀
對我來說,目前尚不清楚是否存在調用cn.Open並拋出異常需要調用dispose的場景。
所以在下面的例子中,“TestNormalWay”和“WhyNotDoItThisWay”之間是否存在任何差異
protected static DbConnection GetConnection()
{
DbConnection cn = new SqlConnection("SomeConnecitonstring... ");
return cn;
}
protected static DbConnection GetConnectionDangerousVersion()
{
DbConnection cn = new SqlConnection("SomeConnecitonstring... ");
cn.Open(); // this will throw.. .dispose not called
return cn;
}
[Test]
public void TestNormalWay()
{
using(var cn = GetConnection())
{
cn.Open();
// do stuff
}
}
[Test]
public void WhyNotDoItThisWay()
{
using(var cn = GetConnectionDangerousVersion())
{
// do stuff
}
}
您編寫代碼的方式總是希望在創建連接后立即打開連接,因此沒有任何區別。
但是,您可以多次打開和關閉連接,並且在設計的代碼中有很大的不同。
我可能想編寫一些代碼,其中我有一個長時間運行的例程,它接受一個連接對象並隨着時間的推移打開並關閉它。 例程可能不關心連接對象是如何創建的。 因此,將創建連接的行為與打開和關閉它的行為分開是有利的。
關於資源管理問題,我同意這不是問題。 創建SQL連接對象本身並不會鎖定任何資源,而是打開它獲取池化連接的行為。 如果open返回異常,我認為假設沒有打開連接是合理的。
我傾向於只返回SqlConnection
的實例而不在方法中調用Open()
。 如果需要,應該這樣做。 您的實用程序功能不需要它。
其中一個原因是,有些對象需要SqlConnection
,但不一定需要打開它們。 例如, SqlDataAdapter
接受SqlConnection
,並在其自身內處理它的打開和關閉。 當然,你可以在傳遞之前打開一個連接,但是你必須明確地關閉它。
回過頭幾步,調用代碼應該負責處理與SqlConnection
完全相關的操作。
您可以在第二個“危險”版本中圍繞.Open()調用放置一個try / catch,這樣如果它在打開時拋出異常仍然處理連接。
在SqlConnection的內部達到頂峰之后,我幾乎確信這無關緊要。 快速測試似乎證實了這一點:
static void Main( string[] args )
{
Func<SqlConnection> getConnection =
() =>
{
var connection =
new SqlConnection(
"Initial Catalog=myDatabase;Server=(local);Username=bogus;password=blah;Connect Timeout=10;" );
connection.Open();
return connection;
};
while(true)
{
try
{
using( var connection = getConnection() )
{
var cmd = new SqlCommand( "SELECT 1", connection ) {CommandType = CommandType.Text};
cmd.ExecuteNonQuery();
}
}
catch ( Exception )
{
// ignore exception
}
}
}
我把這個代碼運行了幾分鍾,並附帶了一個分析器。 它不僅運行速度很快,而且還沒有泄漏任何內存。 這讓我很有信心在GetConnection方法中打開連接是可以的。
當然,此處發布的所有其他論點仍然有效; 如果你要立即使用它,你應該只打開連接。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.