以下是来自SqlDataReader Class
的声明在使用SqlDataReader时,关联的SqlConnection正忙于为SqlDataReader提供服务,除了关闭它之外,不能对SqlConnection执行任何其他操作。
我的代码有两个不同命令使用的一个开放连接。实际上有两种方法。第二种方法是在while(reader.Read())
循环中调用。
我收到间歇性错误 - There is already an open DataReader associated with this Command which must be closed first
。
但为什么不总是抛出错误?
参考
答案 0 :(得分:3)
既然你知道同一个连接上的嵌套数据引用器是个坏主意,你为什么要这样做呢?重构那段代码。
现在回答你的问题,
网络层在PULL模式下不起作用。您打开连接,发出一些命令,然后开始消费结果。请注意,您不拉但消费。它们是有区别的。在您的代码中,while(reader.Read)
循环不会稳定地提取数据。数据在命令执行时开始到达。它会在你的电脑上缓冲。缓冲区有一个限制。如果总数据小于缓冲区大小,则数据传输发生得非常快。如果总数据超过缓冲区大小,那么reader.read()
当然会为下一批提供空间。
这意味着只要第一个datareader获取的数据量非常少,两个DataReaders
就可以使用相同的connection
。所以当第二个datareader尝试使用连接时,连接已经空闲。
两个线程之间存在竞争条件。第一个线程是收集响应第一个命令发送的数据的线程。第二个线程是运行程序的线程。两场比赛都先完成。如果收集器线程能够在主线程命中第二个datareader之前下载所有数据,则可以避免事故。但是如果数据很大或网络速度很慢,或者运气不好就没有得到足够的cpu,那么当连接仍在工作时,主线程会点击第二个datareader。