SQL可能正在泄漏连接,即使我正在调用Connection.Close()

时间:2013-11-22 18:35:04

标签: c# sql linq-to-sql

我有一个线程(通过new Thread(new ThreadStart(...))调用),当我的软件正在运行时,它始终在数据库中进行轮询。

以一种非常简单的方式,它基本上执行以下操作:

void Polling()
{
    Thread.Sleep(500); 
    methodA();
    if (certainTimePassed)
        methodB();
    if (anotherCertainTimePassed)
        methodC();
    ...
}

void methodA()
{
    SIDataContext db = new SIDataContext(_host.Config.ConnectionString);
    if (looksForSomeData())
        raiseSomeEvents();
    db.Connection.Close();
}

运行好几个小时。但是,如果我强调应用程序通过使lookForSomeData()返回总是为真(即不断插入它搜索的数据)并同时使用另一个在数据库中查询大型SELECT的软件部分,最终生成以下内容(总是在MethodA中,可​​能因为它是最常被调用的那个):

  

超时已过期。在获得a之前经过了超时时间   从游泳池连接。这可能是因为所有人都集中了   正在使用连接并达到最大池大小。

我认为这可能是一个更复杂的问题。但由于我只有几个月使用LINQs DataContext()的经验,我不确定。

注意事项/我尝试过:

  • 使用using代替db.Connection.Close()
  • 无法打开连接,引发异常,也无法关闭连接,因为如果在此线程中引发异常,则软件退出
  • raiseSomeEvents()中引发的事件不会累积(可能),因为有某种信号量解决方案只会使事件无法运行。
  • 捕获异常并且什么也不做。该软件速度减慢甚至冻结了一段时间然后恢复正常(似乎连接最终被释放)。

我感谢任何有助于我诊断出问题所在的方法。

4 个答案:

答案 0 :(得分:1)

这可能只是连接池。启动新连接非常昂贵,因此.Net将保持连接打开并重新使用它们。

答案 1 :(得分:1)

你的桌子上有索引吗?大量插入也会导致索引更新,这可能会对您的select语句产生负面影响。 select语句也可能正在使用临时数据库来确保它们是可重复的,同样可能是昂贵的。这些可能会产生累积影响,从而推高完成快速操作所需的时间

答案 2 :(得分:1)

听起来像你的查询运行时间异常(即大于10-15秒)。在这些情况下,连接可能会超时。我建议您尝试使用可能由应用程序传递的任何参数自行运行查询,如果查询需要很长时间,请查看是否有任何方法可以改进SQL。

您始终可以参考:Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. The statement has been terminated

答案 3 :(得分:0)

看一下你的methodA(),并告诉我如果在创建数据上下文之后抛出异常或线程中止但在关闭之前你认为会发生什么?正确答案是连接将保持悬挂,至少在一段时间内。

必须try / finally块中包含与数据库访问有关的任何内容,以便连接作为finally的一部分关闭。最简单的方法是使用using块。我知道你说你试过了,但你应该发布那段代码:

void methodA()
{
    using (SIDataContext db = new SIDataContext(_host.Config.ConnectionString))
    {
        if (looksForSomeData())
            raiseSomeEvents();
    }
}