2013-08-16 51 views
3

下面的示例代码泄漏句柄。处理数从133开始,不到2小时达到900.样本是VS2010和.Net 4.0。这在.Net 3.5上不会发生。 我已经在超过3台机器上重现了这一切,所有Win2008 R2服务器。 SQL 2008 & SQL 2012.这些机器是虚拟机,并且每周都会不断回滚两次,因此很干净。.Net 4.0上的SQL句柄泄漏但不在.Net 3.5上。

//Reference dll are the ones required for SQL 
//.Net 4.0 (not 'Client Profile' version) 
static void Main(string[] args) 
{ 

    string sss = "Data Source=WIN-0BDHQ0IIUFL,1433;Initial Catalog=DB_Mycentral;Persist Security Info=False;User ID=Myuser;Password=123;Connect Timeout=60;Network Library=dbmssocn"; 
    System.Data.SqlClient.SqlConnection connection = new System.Data.SqlClient.SqlConnection(sss); 
    int i = 0; 
    while (true) 
    { 
     i++; 

     Thread.Sleep(1000 * 60 * 60); 
     Console.WriteLine("{0} hrs sleep", i); 
    } 
} 

我在ProcExp.exe中观察到ProcMon.exe和调用堆栈中的活动。 ProcMon.exe反复登录CreateThread()和ExitThread()。然后ProcExp.exe针对新创建的TID显示了 cld.dll!StrongNameErrorInfo + 0x18910。最后,ProcExp.exe中的THREAD对象数被碰撞了一个。整个过程重复一遍又一遍。

Example for leaking of TID 9089: 
CreateThread()/ExitThread() TID:9089 //Log in ProcMon.exe 
cld.dll!StrongNameErrorInfo+0x18910 TID: 9089 //Call-stack in ProcExp.exe 

背景:我写了这个样本来缩小我们生产代码中的泄漏。该代码在.Net 3.5中运行正常,但在.Net 4.0中泄漏。

请让我知道如果我打开连接时必须设置额外的标志。

+2

你所依赖的终结(因为你没有处置),所以除非垃圾收集器运行时,你就不会得到最终确定。 http://dotnettips.wordpress.com/2011/10/24/net-4-0-bug-with-sqlconnection-object/ –

+0

考虑到编写问题花费的时间,搜索Sq​​lConnection Leak Handle会更好...它看起来很有名。这表明,当你有问题时,首先谷歌。 – xanatos

+0

谢谢柯普。我会尝试MS提出的解决方案。 – user1174790

回答

0

使用'using'来确保始终调用dispose方法。

http://msdn.microsoft.com/en-us/library/yh598w02.aspx

//Reference dll are the ones required for SQL 
//.Net 4.0 (not 'Client Profile' version) 
static void Main(string[] args) 
{ 

    string sss = "Data Source=WIN-0BDHQ0IIUFL,1433;Initial Catalog=DB_Mycentral;Persist Security Info=False;User ID=Myuser;Password=123;Connect Timeout=60;Network Library=dbmssocn"; 
    using(System.Data.SqlClient.SqlConnection connection = new System.Data.SqlClient.SqlConnection(sss)) 
    { 

     int i = 0; 
     while (true) 
     { 
      i++; 

      Thread.Sleep(1000 * 60 * 60); 
      Console.WriteLine("{0} hrs sleep", i); 
     } 
    } 
}