嵌套使用关键字进行连接处理。

时间:2017-04-21 15:51:46

标签: c# asp.net .net ado.net

我在c#中使用“使用”关键字。

using(SqlConnection sourceConnection = new SqlConnection())
{
   sourceConnection.Open(); 
   var destinationConnection = new SqlConnection();
   destinationConnection.Open();

}

在上面的代码行中,连接将被释放,或者只有sourceConnection()将被处置。

4 个答案:

答案 0 :(得分:3)

仅处理sourceConnection,即您在using语句中包装的对象。您应该使用另一个using语句来确保destinationConnection也被处置:

using (SqlConnection sourceConnection = new SqlConnection())
using (var destinationConnection = new SqlConnection())
{
   sourceConnection.Open(); 
   destinationConnection.Open();

}

答案 1 :(得分:3)

usingIDisposable界面上运行。忽略变量的范围,它基本上做了类似的事情:

SqlConnection sourceConnection = new SqlConnection();
try
{
   sourceConnection.Open(); 
   var destinationConnection = new SqlConnection();
   destinationConnection.Open();
}
finally
{
    if (sourceConnection != null)
    {
        sourceConnection.Dispose();
    }
}

所以在回答你的问题时,它只能关闭一个。

来自MSDN,来自Robert S的this post

  

C#,通过.NET Framework常见   语言运行时(CLR),自动   释放用于存储的内存   不再需要的对象。   内存的释放是   非确定性;内存被释放   每当CLR决定执行时   垃圾收集。但是,确实如此   通常最好释放有限   文件句柄和文件等资源   网络连接速度快   可能。

     

using语句允许   程序员指定何时对象   使用资源应该发布   他们。提供给使用的对象   声明必须执行   IDisposable接口。这个界面   提供Dispose方法,其中   应该释放对象的资源。

这再次表明它只适用于一个对象:使用的主题。

答案 2 :(得分:2)

只会处理其中一个,您永远不会明确地调用Dispose或包裹using destinationConnection

你可以这样做,两者都将永远处置。

using(SqlConnection sourceConnection = new SqlConnection())
{
   using(SqlConnection destinationConnection = new SqlConnection())
   {
   }
}

答案 3 :(得分:2)

有些人已经注意到,LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { switch(Msg) { case WM_CREATE: hButton=CreateWindow("Button","Click Me",WS_CHILD|WS_VISIBLE,70,60,150,30,hWnd,(HMENU) 1,NULL,NULL); hButton2=CreateWindow("BUTTON","Press here",WS_CHILD|WS_VISIBLE,170,160,250,130,hwnd,(HMENU) 2,NULL,NULL); break; case WM_COMMAND: switch(LOWORD(wParam)) { case 1: //What will the first button do?write it here break; case 2: //What will the second button do?write it here break; } break; } return 0; } 包装using界面,如:

IDisposable

与:

相同
using (var foo = new MyDisposable()) { ... } 

到目前为止一切顺利。 C#实现此目的的原因是非托管资源。为什么?非托管资源要求您在需要时清理内容,而不是垃圾收集器(GC)需要的时间(当内存不足时为f.ex.)。

暂时考虑替代方案:让我们假设您有一个文件。你打开文件,写一些字节,忘记'关闭',然后没有IDisposable关闭它。即使您不再使用该对象,您的文件仍将继续打开。更糟糕的是,如果您的程序退出,您甚至不知道已写入数据。如果你的程序运行的时间足够长,那么在某些时候GC可能会启动并删除你的东西,但在此之前,每次打开文件的其他尝试都可能会给你一个很大的错误。所以,简而言之......:很多痛苦和痛苦。

这就是var foo = new MyDisposable() try { ... } finally { if (foo != null) { foo.Dispose(); } } 解决的问题。

连接,文件,内存访问,网络访问,...基本上所有使用需要清理的东西都会实现IDisposable。即使如果类型实现了IDisposable,你也可以更好地处理它。

所以...... SQL连接实现了IDisposable,SQL Readers实现了IDisposable,等等。就个人而言,在使用它之前,我倾向于检查每种类型是否存在IDisposable接口(所以是的:所有时间)。

一旦你理解了这一点,使用这一切的正确方法是显而易见的:

IDisposable

......等等。

现在,在某些情况下,您显然无法使用using (var sourceConnection = new SqlConnection()) { sourceConnection.Open(); using (var destinationConnection = new SqlConnection()) { destinationConnection.Open(); // ... using (var myReader = srcConnection.ExecuteReader(...)) { // ... } } } ,因为您使用的是不同的方法。怎么解决这个?简单:在具有这些方法的类中实现Dispose Pattern。

更多信息(以及Dispose模式):https://msdn.microsoft.com/en-us/library/b1yfkh5e(v=vs.110).aspx

相关问题