我正在对ADO.Net和EF进行一些实验,以便更好地理解它如何处理SQL Server连接.我发现ADO.Net非常有趣.我正在创建多个任务,调用一个简单的插入SQL脚本,并正确等待处理SqlConnection和SqlCommand.这里没什么特别的,但是...
我正在对ADO.Net和EF进行一些实验,以便更好地理解它如何处理SQL Server连接.
我发现ADO.Net非常有趣.我正在创建多个任务,调用一个简单的插入SQL脚本,并正确等待处理SqlConnection和SqlCommand.这里没什么特别的,但是当10k任务完成处理时,所有SQL连接仍然挂起(我通过运行sp_who确认).清除这些连接的唯一方法是关闭应用程序实例.
这怎么可能呢?我尝试了很多东西来强迫它关闭,= null数据访问实例强制GC但没有…
我试图从这种行为中弄清楚,但我失败了.有线索吗?
static void Main(string[] args)
{
Console.WriteLine(DateTime.Now.ToString("HH:mm:ss"));
for (int i = 0; i < 10000; i++)
{
Task.Run(() =>
{
var dbLegacy = new DataAccessLegacy();
dbLegacy.TableBInsert();
dbLegacy = null;
});
}
Console.ReadKey();
}
public void TableBInsert()
{
using (SqlConnection connection = new SqlConnection(@"Password=qpqp;Persist Security Info=True;User ID=sqlUser2;Initial Catalog=DatabaseA;Data Source=VM2HOSTNAME\VM2INSTANCEA"))
{
using (SqlCommand command = new SqlCommand("DatabaseBInsert", connection))
{
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add("ColAInt", SqlDbType.Int);
command.Parameters[0].Value = (new Random()).Next(0, 5000);
command.Parameters.Add("ColBTinyInt", SqlDbType.TinyInt);
command.Parameters[1].Value = (new Random()).Next(1, 255);
command.Parameters.Add("ColCVarchar", SqlDbType.VarChar);
command.Parameters[2].Value = Convert.ToChar((new Random()).Next(1, 255)).ToString();
command.Parameters.Add("ColDVarcharMax", SqlDbType.VarChar);
command.Parameters[3].Value = Convert.ToChar((new Random()).Next(1, 255)).ToString();
command.Parameters.Add("ColEDecimal", SqlDbType.Decimal);
command.Parameters[4].Value = (new Random()).Next(0, 5000) + 0.5;
command.Parameters.Add("ColFSmallInt", SqlDbType.SmallInt);
command.Parameters[5].Value = (new Random()).Next(0, 5000);
command.Parameters.Add("ColGDateTime", SqlDbType.DateTime);
command.Parameters[6].Value = DateTime.Now;
command.Parameters.Add("ColHChar", SqlDbType.Char);
command.Parameters[7].Value = Convert.ToChar((new Random()).Next(1, 255)).ToString();
command.Parameters.Add("ColINVarchar", SqlDbType.NVarChar);
command.Parameters[8].Value = Convert.ToChar((new Random()).Next(1, 255)).ToString();
command.Parameters.Add("ColJNChar", SqlDbType.NChar);
command.Parameters[9].Value = Convert.ToChar((new Random()).Next(1, 255)).ToString();
connection.Open();
command.ExecuteScalar();
connection.Close();
command.Dispose();
}
connection.Dispose();
}
}
解决方法:
默认情况下,ADO.Net使用connection pooling.从文档(强调我的):
Connection pooling reduces the number of times that new connections must be opened. The pooler maintains ownership of the physical connection. It manages connections by keeping alive a set of active connections for each given connection configuration. Whenever a user calls Open on a connection, the pooler looks for an available connection in the pool. If a pooled connection is available, it returns it to the caller instead of opening a new connection. When the application calls Close on the connection, the pooler returns it to the pooled set of active connections instead of closing it. Once the connection is returned to the pool, it is ready to be reused on the next Open call.
本文标题为:c# – 为什么强制.Close()和使用(…)后SqlConnection仍然打开?
基础教程推荐
- C#利用SFTP实现上传下载 2022-11-19
- 区分C# 中的 Struct 和 Class 2023-03-10
- DataGridView实现点击列头升序和降序排序 2023-05-23
- c# – 使用线程时出现内存不足异常 2023-09-19
- C# 实现俄罗斯方块(附源码) 2023-03-04
- C#迭代器及Unity协程实例解析 2023-02-17
- Unity调取移动端的麦克风进行录音并播放 2023-01-22
- C#中的Task.WaitAll和Task.WaitAny方法介绍 2023-06-04
- c# – 如何获取托管类的原始内存指针? 2023-09-19
- C#委托与匿名委托详解 2022-11-10