关于c#:在同一个SqlConnection上多次调用CreateCommand

Multiple calls to CreateCommand on same SqlConnection

我在C/.net4中有一个Windows窗体应用程序,带有一个SQL 2008后端。我在我的button click事件处理程序中打开了一个sqlconnection,然后调用多个backgroundworkers,每个backgroundworkers在using块内调用连接的createCommand方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
    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。我做错什么了?


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


这些命令是选择(只读)、插入/更新/删除还是什么?在这种情况下,您可能还希望使用DataAdapter,并使用DataAdapter值填充数据集。将e.result设置为该值。

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