SqlConnection立即超时

时间:2018-04-06 20:21:06

标签: c# ado.net connection-timeout

编写一个非常简单的工具来ping SQL服务器并确保可以访问一堆连接字符串,我遇到了一个非常奇怪的问题:在迭代几十个连接字符串时,前半部分超时后我指定的大约多少秒(在这个特殊情况下为11)并记录相应的尝试和异常当前的墙壁时间,但突然间,其中大约十几个瞬间超时,然后恢复正常的超时。

这在一台计算机上运行,​​该计算机对所有要测试的连接字符串中使用的一个IP没有任何网络访问权限。在日志中它看起来像这样:

2018-04-06 15:59:40     Connection name: 
2018-04-06 15:59:40     SQL Error:Connection Timeout Expired.  Th
or the server was unable to respond back in time.  The duration s
2018-04-06 15:59:40     Connection name: 
2018-04-06 15:59:40     SQL Error:Connection Timeout Expired.  Th
or the server was unable to respond back in time.  The duration s
2018-04-06 15:59:40     Connection name: 
2018-04-06 15:59:40     SQL Error:Connection Timeout Expired.  Th
or the server was unable to respond back in time.  The duration s
2018-04-06 15:59:40     Connection name: 
2018-04-06 15:59:40     SQL Error:Connection Timeout Expired.  Th
or the server was unable to respond back in time.  The duration s
2018-04-06 15:59:40     Connection name: 
2018-04-06 15:59:40     SQL Error:Connection Timeout Expired.  Th
or the server was unable to respond back in time.  The duration s
2018-04-06 15:59:40     Connection name: 
2018-04-06 15:59:40     SQL Error:Connection Timeout Expired.  Th
or the server was unable to respond back in time.  The duration s
2018-04-06 15:59:40     Connection name: 
2018-04-06 15:59:40     SQL Error:Connection Timeout Expired.  Th
or the server was unable to respond back in time.  The duration s
2018-04-06 15:59:40     Connection name: 
2018-04-06 15:59:40     SQL Error:Connection Timeout Expired.  Th
or the server was unable to respond back in time.  The duration s
2018-04-06 15:59:40     Connection name: 
2018-04-06 15:59:40     SQL Error:Connection Timeout Expired.  Th
or the server was unable to respond back in time.  The duration s
2018-04-06 15:59:40     Connection name: 
2018-04-06 15:59:40     SQL Error:Connection Timeout Expired.  Th
or the server was unable to respond back in time.  The duration s
2018-04-06 15:59:40     Connection name: 
2018-04-06 15:59:54     SQL Error:Connection Timeout Expired.  Th
or the server was unable to respond back in time.  The duration s
2018-04-06 15:59:54     Connection name: 
2018-04-06 15:59:54     SQL Error:Connection Timeout Expired.  Th
or the server was unable to respond back in time.  The duration s
2018-04-06 15:59:54     Connection name: 
2018-04-06 16:00:08     SQL Error:Connection Timeout Expired.  Th
or the server was unable to respond back in time.  The duration s
2018-04-06 16:00:08     Connection name: 
2018-04-06 16:00:22     SQL Error:Connection Timeout Expired.  Th
or the server was unable to respond back in time.  The duration s
2018-04-06 16:00:22     Connection name: 
2018-04-06 16:00:35     SQL Error:Connection Timeout Expired.  Th
or the server was unable to respond back in time.  The duration s
2018-04-06 16:00:35     Connection name: 
2018-04-06 16:00:49     SQL Error:Connection Timeout Expired.  Th
or the server was unable to respond back in time.  The duration s

看看如何在一堆即时超时后15:59:40在15:59:54记录的最后一个条目是正常的,然后另一个连接立即超时,并且在16:00:08之后的所有内容超时通常是。

代码看起来完美无缺的教科书:

foreach (ConnectionStringSettings cs in ConfigurationManager.ConnectionStrings)
{
    if (cs.Name.Equals("LocalSqlServer") && !args.Contains("NoSkipLocal", StringComparer.OrdinalIgnoreCase)) continue;

    SqlConnectionStringBuilder b = new SqlConnectionStringBuilder(cs.ConnectionString)
    {
        ConnectTimeout = timeout == 0 ? 10 : timeout
    };

    SqlConnection conn = new SqlConnection(b.ConnectionString);
    try
    {
        conn.Open();
        LogToConsole("Connection success", ConsoleColor.Green);
    }
    catch (SqlException sex)
    {
        LogToConsole("SQL Error:" + sex.Message, ConsoleColor.Red);
    }
    catch (Exception ex)
    {
        LogToConsole("Error:" + ex.Message, ConsoleColor.Red);
    }

static void LogToConsole(string message, ConsoleColor color = ConsoleColor.Gray)
{
    ConsoleColor fgColor = Console.ForegroundColor;
    Console.ForegroundColor = color;
    Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "\t" + message);
    Console.ForegroundColor = fgColor;
}

是否有其他人使用ADO.NET SqlConnection对象体验即时超时?我期待连接失败很可能是即时的,但至少信息应该是不同的。但它与~14秒过去完全相同。

1 个答案:

答案 0 :(得分:0)

Pooling = false添加到连接字符串构建器实例以解决此问题。现在每个连接在抛出异常之前等待指定的秒数。

在连接池打开时处理SqlConnection是不够的,ADO.NET池仍然保存特定数据库的条目并存储上一个错误状态,因此在实例化下一个连接对象时如果连接字符串指向相同的连接,则会立即返回超时连接。

在我的特殊情况下,这是一个很好的行为,因为它节省了我测试连接字符串的时间,但在现实世界中它可能代表一种令人讨厌的副作用。