.net - ADO.net 关闭 TCP 连接的速度不够快

标签 .net sql-server ado.net sqlconnection sqlexception

我正在运行一个多线程操作,该操作使用 SqlConnectionParallel.ForEach() 从 SQL Server 数据库中获取数据,并且发生了以下情况:

  • 我将 SqlConnection 包装在 using 语句中,以便正确处理连接。
  • 在成功运行一段时间后,我的进程始终抛出包含在 AggregateException 中的 SqlException(“建立与SQL Server..")
  • 我发现这发生在大约 2^14 (16384) 次数据库调用(所有线程中总共)。
  • 我启动了 perfmon,我可以看到这也是在抛出异常时打开的 TCP 连接数(“Connections Established”计数器)。
  • 我确信我的代码中没有连接泄漏——我查询数据库的地方很少,它们都正确地处理了连接(事实上,我没有其他模式用于查询数据库比 Vanilla using(...))
  • 我关闭了连接池并且发生了相同的行为。
  • 奇怪的是,如果我在 SQL Server 中删除了一个使我的查询速度更快的索引,该操作会成功完成(尽管非常缓慢)- 不会抛出任何异常。我观察到建立的连接数线性上升到大约 13K,然后稳定了一段时间,然后有一些线性下降的时期,所有这些都是在操作运行的过程中进行的。
  • 我的结论是,随着索引的建立,.net 处理数据的速度超过了它关闭连接的速度,并最终达到某种操作系统或 .NET 套接字的最大阈值。如果没有索引,.NET 仍然会维护过多的连接,但它有时间关闭足够多的连接,以免达到最大打开套接字阈值。

我不知道如何指示 .NET 关闭这些连接。我认为当 SqlConnection 被释放时,这会自动神奇地发生。

最佳答案

问题似乎与连接的打开方式有关。我正在使用这个构造函数

public SqlConnection(string connectionString, SqlCredential credential)

似乎 ADO 创建了一个新的连接池,即使 connectionString 相同并且 credential 封装了相同的凭据。我的猜测是 ADO 无法以某种方式将凭据与先前的调用相关联(如果我通过引用相等性使用相同的凭据对象,它可能会起作用?在我的例子中,我在每次调用时都创建了一个新的 SqlCredential)。

由于每次都会创建一个新池,因此 TCP 连接数会激增。我认为这在关闭连接池时也有意义。可能一些套接字或 TCP 设置在这里启动(保持事件状态?)并且操作系统保持连接打开以遵守这些设置。

关于.net - ADO.net 关闭 TCP 连接的速度不够快,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33106463/

相关文章:

c# - 如果时区规则更改,以前保存的日期时间的 UTC 到本地时间转换

c# - 还有其他类似的 ObservableCollection<T> 吗?

sql-server - SSIS 中的日期和时间格式

sql-server - SQL 错误 : Verify that the instance name is correct and that SQL Server is configured to allow remote connections?

sql-server - 如何将表名作为存储过程的输入参数?

f# - 错误: Invalid attempt to call Read when reader is closed?

c# - 单击 [C#] 修改图片框

c# - null 或空检查的代码优化

Sqlite 在创建表时设置默认值

c# - 从 SqlDataReader 填充数组(或数组列表)