这个问题与我之前的一个答案有些相关,它帮助我找到了通过 SqlDataReader 进行这个简单迭代的原因:
m_aFullIDList = New Generic.List(Of Integer)
While i_oDataReader.Read
m_aFullIDList.Add(i_oDataReader.GetInt32(0))
End While
m_iTotalNumberOfRecords = m_aFullIDList.Count
不返回所有记录。结果,当 Generic.List 更改其容量以容纳更多元素(例如,从 2^19 到下一个 2^20)时,此时 SqlDataReader 简单退出,其 Read 方法返回 False,就好像没有更多记录一样。
大多数时候它会安静地退出,不会抛出任何异常。但时不时我会得到:
NullReferenceException {“对象引用未设置为对象的实例。”}
在 System.Data.SqlClient.SqlDataReader.ReadColumnHeader(Int32 i)
在 System.Data.SqlClient.SqlDataReader.ReadColumn(Int32 i, Boolean setTimeout) 在 System.Data.SqlClient.SqlDataReader.GetInt32(Int32 i)
我知道 Reader 使用的存储过程返回的所有记录(它是单列)都是整数值。如果我删除行m_aFullIDList.Add
并将简单的读取值转换为整数变量,或者如果我将通用列表容量预分配给一个已知的大数 - 这个问题就不会发生。显然它只发生在 List 重新分配容量时 - 这会影响读者。
一旦这个结构的容量重新分配超过某个点,我还尝试使用其他结构(ArrayList,甚至 Array,使用 Array.Resize) - 这会破坏 SqlDataReader。
这个 ASP.NET 项目有点复杂,所以当我尝试在一个独立的简单项目中重新创建问题时,该项目仅包含执行阅读器和读入列表 - 问题没有发生。知道发生了什么以及如何解决这个问题吗?