2013-08-16 92 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); 
     } 
    } 
}