【发布时间】:2018-03-04 01:58:15
【问题描述】:
我正在对 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();
}
}
【问题讨论】:
-
自从提出这个问题后,您对此是否有更清楚的了解?提供的答案实际上并没有回答您的核心问题。我有同样的问题,为什么当我运行 90 个任务时,只要可执行文件保持打开状态,就会打开 90 个连接并保持打开状态?
-
我一直在使用控制台应用程序进行测试,我想我已经回答了我自己的问题。默认连接池最大为 100 个连接。如果您通过 90 个任务打开 90 个连接,您将有 90 个打开的连接,只要您的可执行文件根据 MS Docs 运行大约 4-8 分钟,这些连接就会保持打开状态。我确实看到了这种情况。令人惊讶,因为我真的认为接近意味着接近。
标签: c# sql-server sqlconnection