0

我在 C#/.NET4 中有一个带有 SQL 2008 后端的 Windows 窗体应用程序。我在按钮单击事件处理程序中打开一个 SqlConnection,然后调用多个后台工作人员,每个后台工作人员在 using 块内调用连接的 CreateCommand 方法:

    private void btnSubmit_Click(object sender, EventArgs e)
    {
        cn.Open();
        bw01.RunWorkerAsync(x);
        bw02.RunWorkerAsync(x);
        while (bw01.IsBusy || bw02.IsBusy)
            Application.DoEvents();
        cn.Close();
    }

    private void bw01_DoWork(object sender, DoWorkEventArgs e)
    {
        try
        {
            using (SqlCommand cmd = cn.CreateCommand())
            {
                cmd.CommandText = <some SQL>
                e.Result = Convert.ToInt32(cmd.ExecuteScalar());
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
            return;
        }
    }

    private void bw02_DoWork(object sender, DoWorkEventArgs e)
    {
        try
        {
            using (SqlCommand cmd = cn.CreateCommand())
            {
                cmd.CommandText = <some SQL>
                e.Result = Convert.ToInt32(cmd.ExecuteScalar());
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
            return;
        }
    }

该代码有时可以工作,但有时我会出错,最常见的是“当前命令发生严重错误。如果有任何结果,则应丢弃。”

我的连接字符串中有 MultipleActiveResultSets=true 。我究竟做错了什么?

4

2 回答 2

2

您的连接变量不是线程安全的,因为两个线程都在尝试使用它。ADO.NET 将为您管理连接池,因此您应该在每个线程内移动连接创建并使其原子化

于 2012-06-18T04:11:11.727 回答
0

这些命令将是 SELECTs(只读)、INSERTs/UPDATEs/DELETEs 还是什么?您可能还希望在您的情况下使用数据适配器,并使用数据适配器值填充数据集。将 e.result 设置为该值。

这并不能真正解决您的问题,但您可能还想设置 sqlcommand 的 CommandType。

于 2012-06-18T04:40:29.187 回答