【问题标题】:How to run SqlDataReader and SqlDataAdapter concurrently?如何同时运行 SqlDataReader 和 SqlDataAdapter?
【发布时间】:2019-07-02 09:25:39
【问题描述】:

如何更正代码,使异常不再出现?

SqlConnection
    sqlCnn = new SqlConnection("Connection String");

SqlCommand
    sqlCmdSelect = new SqlCommand("SQL SELECT statement;", sqlCnn),
    sqlCmdUpdate = new SqlCommand("SQL UPDATE statement;", sqlCnn);

Thread
    t1 = new Thread(()=>{
        SqlDataReader sdr;
        while(true)
        {
            sdr = sqlCmdSelect.ExecuteReader();
            // Do some works
            sdr.Close();
        }
    }),
    t2 = new Thread(()=>{
        SqlDataAdapter sda;
        while(true)
        {
            using(sda = new SqlDataAdapter())
            {
                // Do some works
                sda.UpdateCommand = sqlCmdUpdate;
                if(!sdr.IsClosed) sdr.Close();
                sda.UpdateCommand.ExecuteNonQuery();
            }
        }
    });

t1.Start();
t2.Start();

System.InvalidOperationException:“已经有一个打开的 DataReader 与此命令关联,必须先关闭。”

【问题讨论】:

  • 你为什么要首先这样做?它不会让您的代码运行得更快,它可能会导致阻塞或死锁。简单地使用SqlDataAdapter 进行更新会显着降低性能。无论您想做什么,使用 SQL 或使用适当的技术(如批量插入或批量更新)可能更容易完成
  • 您首先要做什么,为什么要同时阅读和更新?也许您只需要一个UPDATE FROM .... WHERE...

标签: c# sql-server multithreading


【解决方案1】:

其实你可以使用MARS在单个连接上进行多个操作:

多活动结果集 (MARS) 是一种适用于 SQL 的功能 服务器允许在单个上执行多个批处理 联系。启用 MARS 以与 SQL Server 一起使用时,每个命令 使用的对象将会话添加到连接。

要启用它,只需通过添加MultipleActiveResultSets=True 来修改您的连接字符串,如下所示:

Data Source=MSSQL1;Initial Catalog=AdventureWorks;Integrated Security=SSPI;MultipleActiveResultSets=True

不需要其他代码更改,但请记住这是配置更改,因此如果您有一些环境设置,例如测试、登台,您也需要将此更改传播到这些环境。

【讨论】:

    【解决方案2】:

    正如例外所说,您不能在同一个连接上执行两个操作。

    我会创建两个SqlConnection 类的对象,并在线程中分别使用它们。

    或者,您可以在执行 SQL 语句时使用一些同步(lockSemaphore),但这与您想要做的完全相反。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-12
      • 1970-01-01
      • 2013-02-06
      • 2020-07-20
      • 2019-11-25
      • 2011-07-23
      相关资源
      最近更新 更多