2012-07-08 137 views
1

我見過這樣的(不連續線,但在相同的功能範圍內)的一些代碼:.NET功能範圍陰影

Dim con1 As SqlConnection 
con1 = New SqlConnection 
'More code here 
con1 = New SqlConnection 
con1 = Nothing 

我相信這僅僅是一個錯誤,但我想檢查這裏沒有一種形式的陰影,我不知道。第一個con1變量會發生什麼變化?我認爲它是無法訪問的,因爲沒有提及對象。

+3

它的重新分配,因此無法再訪問 - 現在的參考點在一個SqlConnection的新實例。這可能是一件壞事,特別是當連接打開的時候,因爲直到對象被[非確定性地]處置時它纔會被關閉。請(請!)始終考慮在Using語句中包裝SqlConnection,SqlCommand等的實例 - 請參閱http://msdn.microsoft.com/en-us/library/htd05whh(v=vs.80).aspx – dash 2012-07-08 21:21:45

+1

只有一個變量。 – 2012-07-08 21:21:58

+0

對我來說這是一個錯誤。 SqlConnection應該用Close/Dispose或'using'語句來處理。確實垃圾收集器會處理丟失的處理,但是如果在非常嚴格的循環中調用此代碼會發生什麼? – Steve 2012-07-08 21:27:40

回答

5

該函數的生命週期內這裏發生了什麼

con1指向兩個不同的對象。第二

con1 = New SqlConnection 

執行後

第一個目的,由第一

con1 = New SqlConnection 

創建不再被引用。

這是內存泄漏嗎?

號是不再被引用最終將被安置的對象,則GC決定這樣做。但它資源泄漏。每次關閉SQL連接失敗時(假設它已打開並且不僅僅分配了),則會使資源無法再使用。 GC將觸發時內存低,所以你肯定會在最近收復未引用的對象內存當系統內存不足(也將重新獲得在該點的數據庫連接)。然而,低資源不是觸發GC。在GC決定啓動並釋放SqlConnection對象(包括它們囤積的數據庫連接)之前,您可以完全從數據庫連接運行。

修復代碼

由於SqlConnection的必須關閉,以釋放連接,直到GC決定出售它的第一個對象會流連。 這是一件壞事,因爲SQL連接是一種只能根據需要保留的資源。

調用指定新SqlConnection對象將改善情況之前關閉()第一個連接(也,調用Close()在二審離開變量的作用域之前)。但是,如果你在代碼的某個地方得到一個異常,如果沒有適當的異常處理,你仍然會留下未配置的對象,直到GC開始運行。總是要把異常處理放在任何管理資源的東西上,比如這個。

把異常處理到位對於這種情況最好的方法是使用Using關鍵字。我從來沒有寫過一行VB。網到現在爲止,但這裏是我在正確的版本代碼的嘗試:

Dim con1 As SqlConnection 

Using con1 
    con1 = New SqlConnection 
End Using 

'More code here 

Using con1 
    con1 = New SqlConnection 
End Using 

' NOTE: I believe the following is unnecessary, but was necessary in VB6 and prior 
' con1 = Nothing 
+0

不,在VB6中從來沒有必要(除非你有一個循環參考的情況,在這種情況下是的,你必須手動打破鏈)。 – GSerg 2012-07-08 21:32:39

+0

實際上'SqlConnection'的構造函數什麼都不會導致內存泄漏(所有數據庫的東西都在'Connection.Open'中完成)。 http://stackoverflow.com/a/8408475/284240 – 2012-07-08 21:37:59

+0

@TimSchmelter:當然,但這似乎是相當合理的,「這裏更多的代碼」實際上會對連接做些什麼:-) – 2012-07-08 21:39:43