【问题标题】:SqlConnection timeout odditiesSqlConnection 超时异常
【发布时间】:2013-06-02 07:59:29
【问题描述】:

我遇到了一个奇怪的问题,连接尝试的剩余超时似乎在多次尝试后仍然存在。

我有一个输入连接信息的简单窗口,带有连接和取消按钮。

当用户点击连接时,会执行以下代码:

 DisableControls();
 if((bool)AutoAuthenticated.IsChecked)
 {
     ((MainWindow)Owner).myConnection = new System.Data.SqlClient.SqlConnection
                                          ("server="+ServerName.Text + ";"+
                                          "Trusted_Connection=yes;"  +
                                          "database="+DatabaseName.Text + ";" +
                                          "connection timeout=3");
 }
 else
 {
     ((MainWindow)Owner).myConnection = new System.Data.SqlClient.SqlConnection
     ("user id="+UserName.Text+";" +
     "password="+Password.Password+";" +
     "server="+ServerName.Text+";" +
     "Trusted_Connection=no;" +
     "database="+DatabaseName.Text+";" +
     "connection timeout=3");
 }

 await ConnectToServer();

这是 ConnectToServer 函数:

private async Task ConnectToServer()
{
    //using (((MainWindow)Owner).myConnection)
    //{ 
        await ((MainWindow)Owner).myConnection.OpenAsync();
    //}
}

出于测试目的,超时属性现在很小。

无论如何,如果用户在连接时点击取消按钮:

private void Cancel_Click(object sender, RoutedEventArgs e)
{
    if (((MainWindow)Owner).myConnection != null &&
        ((MainWindow)Owner).myConnection.State ==
            System.Data.ConnectionState.Connecting)
    {
        ((MainWindow)Owner).myConnection.Close();
        EnableControls();
    }
    else
    {
        this.Close();
    }
}

现在,如果我输入虚假的详细信息并将其设置为超时,那么我会通过“未找到网络路径”捕获异常。

如果我在此之后再次尝试连接(或者可能是下一次尝试之后的连接,具体取决于我按下取消按钮的速度),它在按下连接按钮后几乎立即超时,无需等待时间它应该是。

我不确定我在这里做错了什么,我尝试过重置 SqlConnection 对象,但我认为每次点击连接时将其设置为新的 SqlConnection 应该已经这样做了吗?

【问题讨论】:

  • 这与 async-await 无关,对吧?如果你调用 SqlConnection.Open() 而不是 SqlConnection.OpenAsyc 会发生同样的事情,对吧?
  • 您是否知道您使用该连接字符串构建代码创建了多少个字符串?仅使用 string.Format 或 StringBuilder 将是一个巨大的好处,但是,由于您专门构建 SQL 连接字符串,所以 SqlConnectionStringBuilder
  • 我使用的是OpenAsync(),以便应用程序在尝试连接时不会锁定。我刚刚测试过,如果我只使用Open(),也会发生同样的事情。另外,当你说“你知道你正在创建多少个字符串”时,我不确定你所说的会有什么帮助。传入的参数可能会发生变化,所以每次调用这个函数时我都会重建字符串,不管我是怎么做的。

标签: c# wpf timeout async-await sqlconnection


【解决方案1】:

我发现我错过了什么。即使关闭连接、处理对象、将其全部保存在 using 语句中,问题仍然存在,因为还有另一个我不知道的元素 - 连接池。

我仍然需要对此进行一些阅读,但基本上它会重用旧的连接信息等以节省资源等。

有更多信息here,但如果这有助于其他有类似问题的人,请在关闭连接时调用ClearPool() 函数:

示例(在我的异常处理代码中,在我调用 Close() 之后):

System.Data.SqlClient.SqlConnection.ClearPool(((MainWindow)Owner).myConnection);

显然,从资源使用的角度来看,最好仅在您不需要重用连接时才调用该函数,但也就是说,我仍然需要阅读此内容,所以不要相信我的话为它!

【讨论】:

  • 似乎在多线程应用程序(例如网络应用程序)中,仅调用 .ClearPool() 可能会重置池中仍处于活动状态/在其他线程中使用的任何连接。也许最好将打开连接作为同步操作,并将您的 await 置于更高的抽象级别。它只是将任务分成更大的块。
  • 但我仍然想以一种不妨碍 UI 的方式进行操作。由于我禁用了控件,因此用户不能一次打开多个连接。等待发生在一个事件中(点击连接按钮),所以我不确定我能做到多高?另外,我怎么可能同时使用 Sqlconnection 对象进行其他连接?我以为我只能将一个 Sqlconnection 用于一个...sql 连接,并且如果我一次想要多个连接,我将需要多个 Sqlconnection 对象。
  • 我对@9​​87654324@ 的调用应该只影响我传递给它的SqlConnection 对象,不是吗?我没有打电话给ClearAllPools()。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-23
  • 2018-03-27
  • 1970-01-01
  • 1970-01-01
  • 2013-01-29
相关资源
最近更新 更多