与Npgsql和async的并发连接数

时间:2017-02-14 23:15:44

标签: c# asynchronous npgsql

我试图最大化PostgreSQL数据库的吞吐量,并且可以通过从线程池转移到异步查询来获得巨大的性能飞跃。这是执行所述查询的代码的async版本:

using (var conn = new NpgsqlConnection(connStr)) {
    await conn.OpenAsync();
    var id = await conn.ExecuteScalarAsync<long>(
        "my_proc",
        param_obj,
        commandType: CommandType.StoredProcedure,
        commandTimeout: 0
    );
    return id;
}

以前,当使用线程池时,我可以通过简单地设置线程数来设置任何给定时间的最大打开连接数(如果我超过MaxPoolSize,我会看到池耗尽/超时异常,如预期的那样) 。但在这种情况下,连接数量不会很快爆炸吗?也许有一种更为规范的做法,我不知道。

1 个答案:

答案 0 :(得分:4)

您的代码是异步的这一事实并不(通过它自己)以任何方式改变连接池的工作,也不会(再次,它自己)更快地耗尽池。在OpenAsync()完成(异步)的那一刻,已经从池中为您的代码分配了一个连接,并且在它被处置之前将被视为忙。这与同步代码中的工作方式根本不同;唯一的区别是,在同步版本中,所有I / O上都有一个线程阻塞,但在异步版本中却没有。

现在,似乎在您之前的同步版本中,您通过设置执行数据库代码的线程数来控制并发打开的连接数。由于异步,线程会在I / O产生后产生,这显然不相关。相反,您可以简单地控制您(同时)调用上面代码的次数。例如,您可以运行100个参数值的代码,然后使用Task.WhenAny()等待,直到其中任何一个操作完成。当发生这种情况时,您可以执行另一个任务(使用新的参数值),依此类推。