“使用”块线程是否安全?

时间:2015-08-07 05:37:27

标签: c# multithreading concurrency thread-safety

如果我从多个线程调用一些数据访问方法,我是否需要锁定数据库调用周围的代码以确保一致性,或者是否使用原子下的using语句?

public static DataRow GetData(Int32 id)
{
    using (SqlConnection con = new SqlConnection(connectionString);)         
    {
        con.Open();
        SqlCommand cmd = ...
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Parameters.Add(...)
        cmd.Parameters.Add(...)
        DataTable dt = new DataTable();
        return new SqlDataAdapter(cmd).FillWithRetry(dt, sqlGetEmail.CommandText);
    }
}

我认为一个线程不会影响定义的连接对象和另一个线程的“使用中”。

2 个答案:

答案 0 :(得分:7)

使用语句 nothing 来处理线程安全(或缺少)。

它们仅确保在块结束时调用所使用对象的Dispose方法;但在其他方面等同于手册try..finally Dispose

在这种特殊情况下:由于在每个线程上打开了 new 连接,因此它是“线程安全的”#。它仍然可能不是原子的。数据库或其他共享状态。

答案 1 :(得分:2)

  

我认为一个线程不会影响定义的连接对象和另一个线程的“使用中”。

所以我想你担心连接的并发访问。 using语句不是锁。如果您想使用独占连接或任何其他实例,您应该使用:

lock(myConnection)
{
    // your code
}

using关键字对于here

所描述的内容

但我认为此处存在其他误解:。在您的示例中,您的连接是一个局部变量,当控制流进入您的GetData方法时(即使在不同的线程中),实例化多次。因此,即使控制流重新进入该方法(并且在不同的线程中),也不会使用共享连接实例,每个进入该方法的人都会创建自己的实例。

如果连接实例是参数不同。然后你应该担心关于并发,并使用锁。

结论:在您的示例中,您不必担心连接实例并发访问,也不需要使用任何锁定语义。

有趣的是,使用using的样本确实是正确的,因为Connection是IDisposable,所以你应该使用try / finally或更好的快捷方式应用一个确定性的处置保护:using关键字。