我写了一个简单的应用来测试连接字符串中的Max Pool Size = 50。
static void Test1()
{
string connectionString = @"Server=.;Database=appsdb;Trusted_Connection=True;Application Name=JH;Max Pool Size=50";
for (int i = 1; i <= 100; i++)
{
var conn = new SqlConnection(connectionString);
conn.Open();
using (var cmd = new SqlCommand("select newid()", conn))
{
using (var r = cmd.ExecuteReader())
{
while (r.Read())
{
Console.WriteLine($"[{Thread.CurrentThread.ManagedThreadId}] {i} - {r.GetGuid(0)}");
}
}
}
}
Console.WriteLine("Done");
Console.ReadLine();
}
我最初运行51次连接期望第51次连接失败,但事实并非如此。
它始终在 71st 连接失败,但有以下异常:
System.InvalidOperationException:'超时已过期。从池中获取连接之前经过的超时时间。这可能是因为所有池连接都在使用中并且达到了最大池大小。'
当我使用sp_who
(或sp_who2
)查看时,我发现确实存在 50 连接。这令人费解
我能理解.NET是否会以某种方式让你重用连接,但为什么要在71?
为什么只允许额外的20(逻辑)连接?为什么不是19或47?
答案 0 :(得分:4)
看起来你没有保持for
循环迭代之间的联系。这意味着每次遍历for
循环时,前一次迭代的连接都有资格进行垃圾收集,这会将底层连接释放回池中。所以:可能是垃圾收集发生了。要测试这一点:保持使用的连接可达 - 将它们放在列表或类似内容中。例如:
var list = new List<SqlConnection>();
for (int i = 1; i <= 100; i++)
{
var conn = new SqlConnection(connectionString);
list.Add(conn);
conn.Open();
// ... etc removed
}
GC.KeepAlive(list);