C# 连接池已耗尽

C# 连接池已耗尽,c#,npgsql,C#,Npgsql,使用parallel foreach将数据插入数据库时,出现以下错误: 连接池已耗尽' 在将一些数据插入数据库之后 try { var connection = ConfigurationManager.ConnectionStrings["Connection"].ConnectionString; Parallel.ForEach(Enumerable.Range(0, 1000), (_) => { using (var connectio

使用parallel foreach将数据插入数据库时,出现以下错误:

连接池已耗尽'

在将一些数据插入数据库之后

try
{
    var connection = ConfigurationManager.ConnectionStrings["Connection"].ConnectionString;

    Parallel.ForEach(Enumerable.Range(0, 1000), (_) =>
    {
        using (var connectio = new NpgsqlConnection(connection))
        {
            connectio.Open();
            using (var command = new NpgsqlCommand("fn_tetsdata", connectio) { CommandType = CommandType.StoredProcedure })
            {
                command.Parameters.AddWithValue("firstname", "test");
                command.Parameters.AddWithValue("lastname", "test");
                command.Parameters.AddWithValue("id", 10);
                command.Parameters.AddWithValue("designation", "test");

                command.ExecuteNonQuery();
            }
            connectio.Close();
        }
    });
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

使用MaxDegreeOfParallelism约束parralelism的数量,默认情况下,它可能超过您拥有的DB连接数。在并行工作和不破坏数据库之间找到平衡:

Parallel.ForEach(yourListOfStuff,
    new ParallelOptions { MaxDegreeOfParallelism = 10 },
    stuff => { YourMethod(stuff); }
);

我假设您正在使用并行性来提高性能。如果是这样,那么首先你需要一个基线。以串行方式运行1000个查询,每次都创建一个新连接,实际上只是从池中提取一个连接

然后使用相同的连接对象进行尝试,看看性能是否有所提高

然后尝试使用come命令对象,只需更改参数值

然后用你没有创建1000个连接对象的同一个连接并行地尝试,你已经尝试过了


如果您通过使用并行性获得了显著的性能改进,我会感到惊讶,因为并行提高了CPU限制任务的性能,并且数据查询通常比CPU更受I/O的限制。

默认连接池大小为20,所以要么增加连接,要么减少连接。我只是想知道你为什么会这样做。。。你是否意识到,通常最好在一个批处理中完成大量工作,而不是抛出大量连接、做一些工作、断开连接等线程?我不相信默认池大小是20-@MurrayFoxcroft,他指的是连接池大小,而不是线程池大小,尽管我认为默认值是100,而不是20。无论如何,在这种情况下,绝对不需要创建多个连接。同意,他应该打开一个连接,然后根据产生最佳性能的内容并行化/批处理,尽管SQL连接管理器应该在这里为您做一些tintelligence。