1

這個問題具有一定的相關my previous one答案。當Generic.List改變其容量以容納更多元素時(例如從2^19到下一個2^20),當SqlDataReader簡單退出時,它的Read方法返回False,就好像沒有更多記錄一樣。.SqlDataReader.ReadColumnHeader的NullReferenceException

大多數時候它安靜地退出,沒有任何例外。但每一個現在,然後我得到:

的NullReferenceException {「對象引用不設置到 對象的實例。」}

在System.Data.SqlClient.SqlDataReader.ReadColumnHeader(我的Int32 )
在System.Data.SqlClient.SqlDataReader.ReadColumn(我的Int32,布爾 的setTimeout)在System.Data.SqlClient.SqlDataReader.GetInt32(的Int32 I)

我知道一個事實,即所有記錄返回由Re使用的存儲過程ader(它是一個單獨的列)是整數值。如果我刪除行m_aFullIDList.Add,而不是簡單的讀取值到一個整數變量,或者如果我預先分配通用列表容量到一個知道大量 - 這個問題沒有發生。顯然它只發生在List重新分配容量時 - 這會影響讀者。

一旦這個結構的容量被重新分配超過某一點,我也試圖使用其他結構(ArrayList,甚至數組,使用Array.Resize) - 這打破了SqlDataReader。

這個ASP.NET項目有點複雜,所以當我試圖在一個獨立的簡單項目中重新創建問題時,這個項目只包含執行讀取器和讀入List - 問題沒有發生。任何想法正在發生什麼以及如何解決這個問題?

+1

我很確定您遇到以下兩種症狀之一:應用程序域內存不足**或**讀取器正在超時。 –

+0

@neoistheone感謝您的及時迴應。我考慮過這個問題,但連接和命令超時都設置爲比SP執行更大的值(我是否缺少其他超時?),而且我似乎也有很多內存(預先分配容量似乎也行得通) –

回答

0

我想我終於明白了。

在我的代碼邏輯有兩個步驟 - 調用返回SqlDataReader的功能,然後使用該讀者在另一個函數來填充列表:

Dim oReader as SqlDataReader = GetTheReader() 

FillTheList(oReader) 

功能GetTheReader()看起來是這樣的:

Function GetTheReader() as SqlDataReader 
    Dim oConn As New SqlConnection("Connection String") : oConn.Open() 
    Dim oComm As New SqlCommand("Stored Procedure", oConn) 

    Dim oReader As SqlDataReader = oComm.ExecuteReader(CommandBehavior.CloseConnection) 

    Return oReader 
End Function 

它打開連接作爲本地當函數返回給調用者時超出範圍的變量。當通用列表被填充後,另一個容量分配垃圾收集通過銷燬過時變量(並關閉該連接)來聲明內存。我留下了一個沒有有效連接的SqlDataReader。

我目前的解決方案是創建GetTheReader函數之外的連接並將其作爲參數之一傳遞。