C#关于线程安全的问题

时间:2009-03-13 12:13:57

标签: c# sql multithreading thread-safety

我正在使用线程池进行一些繁重的处理以及一些sql。目前我在需要时打开sql连接,运行查询然后关闭它们。这很好用。该应用程序一直运行没有问题。随着这个应用程序正在做更多的工作,它正在使用更多的线程。更多线程意味着更多SQL连接的打开/关闭。在SQL 2005中,这实际上会破坏服务器。我的测试服务器大约每天执行175次事务。其中大约150个正在master数据库中运行,并且是“ValidateSQLLogin”。

我要更改应用程序,以便每个线程都拥有自己的连接,然后在线程周围传递此连接。

所以我的问题是:

如果一个SQL连接对象是在一个线程中本地创建的,然后通过ref传递给另一个类的静态函数,那么这会不安全吗?

void ThreadA()
{
    SqlConnection a = new SqlConnection(....);
    MyStaticClass.DoStuff(ref a);
}

void ThreadB()
{
    SqlConnection b = new SqlConnection(....);
    MyStaticClass.DoStuff(ref b);
}

static void MyStaticClass.DoStuff(ref SqlConnection sql)
{
    // Do stuff with sql
}

我最初的想法是它不安全,因为10个线程可以同时调用相同的静态函数,每个线程都传递自己的连接对象。

以前,静态函数打开了自己的连接,并在完成后关闭它们。

如果不安全,最好的解决方法是什么。我需要尝试最小化Sql连接的打开/关闭。

由于

加雷

6 个答案:

答案 0 :(得分:5)

静态函数的参数与静态字段不同。每次执行静态函数都将使用不同的连接副本。您甚至不需要将参数作为参考(仅当您想要更改它们时才需要参考参数)。

答案 1 :(得分:2)

每个线程都有自己的堆栈,参数和局部变量存储在堆栈中,因此几个线程调用相同的静态方法没有问题。每个方法调用都有自己的参数和局部变量。

但是没有理由通过引用传递SqlConnection

答案 2 :(得分:0)

正如其他人所说,从多个线程调用静态方法本身并不存在危险。但是,如果静态方法修改/访问静态字段*而不是仅使用您传递的参数,则需要使其成为线程安全的。

  • exception:某些值类型使用原子操作进行访问/写入,并且对这些操作隐式线程安全。但是,在检索和更新这些条件的逻辑中仍可能出现竞争条件。

答案 3 :(得分:0)

如果您有这样的事务负载,我建议保留一个静态连接,在您进行此事务时保持打开状态,当负载大大减少或为空时,它会自动关闭,并且新请求会再次打开

答案 4 :(得分:0)

尝试以下方法:

您可以使用lock语句来阻止其他线程进入您正在使用此连接的代码块,其他线程会自动等待,直到完成上一个线程,然后进入此段。只需确保您锁定的对象对您的静态类是私有的。

答案 5 :(得分:-2)

在.Net中,所有静态成员都是线程安全的。