LinqToSQL ExecuteReader 需要一个打开且可用的连接

LinqToSQL ExecuteReader requires an open and available Connection

我知道这个问题已经被问过很多次了,但是 none 的答案符合我的问题。 我有一个线程计时器每 30 秒触发一次,它查询一个负载很重的 MSSQL 数据库。如果我需要更新我正在使用的控制台应用程序中的数据,我会使用 Linq To Sql 来更新存储在内存中的数据。

我的问题是有时会收到错误 ExecuteReader 需要一个打开且可用的连接。

来自线程定时器的代码触发了一个 Thread.Run(reload()); 连接字符串是

//example code
void reload(...
    string connstring = string.Format("Data Source={0},{1};Initial Catalog={2};User ID={3};Password={4};Application Name={5};Connect Timeout=120;MultipleActiveResultSets=True;Max Pool Size=1524;Pooling=true;"
 settings = new ConnectionStringSettings("sqlServer", connstring, "System.Data.SqlClient");

  using (var tx = new TransactionScope(TransactionScopeOption.Required,
                  new TransactionOptions() { IsolationLevel = IsolationLevel.ReadUncommitted }))
                {

                    using (SwitchDataDataContext data = new SwitchDataDataContext(settings.ConnectionString))
                    {
                        data.CommandTimeout = 560;

然后我做了很多 linqtosql 搜索。异常有时会发生,但并不总是在同一个查询中。就像连接被打开并被强制关闭。
有时异常会显示当前状态为“打开”、“关闭”、“正在连接”。我向 SQL 数据库添加了一个更大的线程池,但似乎没有任何帮助。

我在程序的其他部分也有 ADO,没有任何问题。

我相信你的问题是事务范围也有超时。根据 this answer,默认超时为 1 分钟。因此事务在您的命令执行之前很久就超时了(560 秒 = 9.3 分钟左右)。您需要在您正在创建的 TransactionOptions 对象实例中设置超时 属性

new TransactionOptions()
{ 
    IsolationLevel = IsolationLevel.ReadUncommitted, 
    Timeout = new TimeSpan(0,10,0) /* 10 Minutes */ 
}

您可以通过将 TransactionScope 超时设置为较小的值以强制其超时来验证这确实是问题所在。

我将 Linq To Sql 更改为 Entity Framework 并收到了相同类型的消息。我相信问题是延迟加载。在 collections 在另一个线程上准备就绪之前,我正在使用它。我刚刚将 .Include("Lab") 添加到我的 collection 以加载整个 collection 并且它似乎解决了问题。