I was looking at some code and discussing it with co-workers.
Specifically a section of code that looks like this.
[Test]
public void TestNormalWay()
{
using(var cn = GetConnection())
{
cn.Open();
// do stuff
}
}
The question came up:
“why not move the cn.Open into the GetConnection method.”
I said that if “Open” throws an exception dispose would not get called. His response was
“So what. The connection wasn’t opened so why would it need to get
closed (or disposed)?”
For me it is just a matter of not wanting to know if or if not I NEED to dispose/close so I would repeat the cn.Open in the code instead of moving it into the shared function.
BUT it is interesting… so I did some reading at SQL Server Connection Pooling (ADO.NET)
To me it isn’t clear if there exists a scenario in which calling cn.Open and it throws and exception where dispose would need to be called.
So in my example below is there any difference really between “TestNormalWay” and “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
}
}
The way you’re writing your code you always want to open the connection as soon as it’s created so there is no difference.
However you can open and close a connection several times and in code designed to do that there is a big difference.
I might want to write some code where I have a long running routine that takes a connection object and over time opens and closes it. The routine might not care how the connection object was created. Therefore it’s an advantage to separate the act of creating the connection with the act of opening and closing it.
With regards the resource management question I’d agree it’s not an issue. Creating an SQL connection object in itself doesn’t lock any resources, it’s the act of opening it that acquires a pooled connection. If the open returns an exception I think it’s reasonable to assume that the connection wasn’t opened.