使用多个阅读器时出现间歇性错误

时间:2013-12-12 14:53:28

标签: c# ado.net sqldatareader

以下是来自SqlDataReader Class

的声明
  

在使用SqlDataReader时,关联的SqlConnection正忙于为SqlDataReader提供服务,除了关闭它之外,不能对SqlConnection执行任何其他操作。

我的代码有两个不同命令使用的一个开放连接。实际上有两种方法。第二种方法是在while(reader.Read())循环中调用。

我收到间歇性错误 - There is already an open DataReader associated with this Command which must be closed first

但为什么不总是抛出错误?

参考

  1. Default Result Set Processing and Multiple Active Result Sets
  2. SQL Server Connection Basics
  3. Regarding a small confusion about DataReader

  4. enter image description here

1 个答案:

答案 0 :(得分:3)

  

既然你知道同一个连接上的嵌套数据引用器是个坏主意,你为什么要这样做呢?重构那段代码。

现在回答你的问题,

网络层在PULL模式下不起作用。您打开连接,发出一些命令,然后开始消费结果。请注意,您不消费。它们是有区别的。在您的代码中,while(reader.Read)循环不会稳定地提取数据。数据在命令执行时开始到达。它会在你的电脑上缓冲。缓冲区有一个限制。如果总数据小于缓冲区大小,则数据传输发生得非常快。如果总数据超过缓冲区大小,那么reader.read()当然会为下一批提供空间。

这意味着只要第一个datareader获取的数据量非常少,两个DataReaders就可以使用相同的connection。所以当第二个datareader尝试使用连接时,连接已经空闲。

两个线程之间存在竞争条件。第一个线程是收集响应第一个命令发送的数据的线程。第二个线程是运行程序的线程。两场比赛都先完成。如果收集器线程能够在主线程命中第二个datareader之前下载所有数据,则可以避免事故。但是如果数据很大或网络速度很慢,或者运气不好就没有得到足够的cpu,那么当连接仍在工作时,主线程会点击第二个datareader。