我已经使用 Dapper 编写了一些代码来将一些数据写入 SQL Server。在继续其他工作之前,我不需要等待此写入完成,所以想使用 Task.Run() 使其异步。
我有(使用)语句在我系统的其余部分调用它:
using (IDataAccess ida = new DAL())
{
ida.WriteMessageToDB(id, routingKey, msgBody);
}
我的 DAL 会在运行 using 语句时自动检查 dbConnection.State,如果它已关闭则尝试进行简单修复。这适用于任何非异步/TPL 选择调用。
但是,当我同时抛出大量写入时,Task.Run() 代码会因为其中一些连接关闭而崩溃 - 本质上我认为代码的并行性质意味着状态是被其他任务关闭。
我通过检查打开 Task.Run() 代码中的 Connection.State 来“解决”这个问题,这似乎已经“解决”了这个问题。像这样:
Task.Run(() =>
{
if (dbConnection.State == ConnectionState.Closed)
{
dbConnection.Open();
}
if (dbConnection.State == ConnectionState.Open)
{
*Dapper SQL String and Execute Commands*
}
});
在此之后,当我从 SSMS 运行 SELECT * FROM sys.dm_exec_connections
时,我看到了更多的连接。值得期待吗?
现在我的理解是:
- Dapper 不处理连接池
- SQL Server 应该自动处理连接池吗?
这个解决方案有什么问题吗?或者更好的方法?出于明显的原因,我想使用连接池,并且尽可能轻松。
提前致谢。
最佳答案
谢谢 Juharr - 我对你的回复投了赞成票。
为了引用别人,我把write函数改成了await和Dapper async:
private async Task WriteMessageToDB(Guid id, string tableName, string jsonString)
{
string sql = *Redacted*
await dbConnection.ExecuteScalarAsync<int>(sql, new { ID = id, Body = jsonString });
}
然后在调用者中创建一个新任务来监控结果。
这在负载下始终如一地工作,也没有看到创建过多的新连接。
关于C#、Dapper、SQL Server 和连接池,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43874607/