C#:在Parallel.ForEach内打开SqlConnection时出现连接错误
我有一个.NET核心C#控制台应用程序,它执行大量计算,然后使用Dapper(和Dapper.Contrib)将结果写入SQL Server 2016开发者版数据库。我遇到的问题是,当我并行运行许多项(例如,大于1000项)时,我开始在C#:在Parallel.ForEach内打开SqlConnection时出现连接错误,c#,parallel-processing,.net-core,dapper,parallel.foreach,C#,Parallel Processing,.net Core,Dapper,Parallel.foreach,我有一个.NET核心C#控制台应用程序,它执行大量计算,然后使用Dapper(和Dapper.Contrib)将结果写入SQL Server 2016开发者版数据库。我遇到的问题是,当我并行运行许多项(例如,大于1000项)时,我开始在.Open()调用中出现间歇性连接故障,并说 出现与网络相关或特定于实例的错误 这通常发生在已经成功插入数千行之后 代码的简化版本如下所示: Parallel.ForEach(collection, (item) => {
.Open()
调用中出现间歇性连接故障,并说
出现与网络相关或特定于实例的错误
这通常发生在已经成功插入数千行之后
代码的简化版本如下所示:
Parallel.ForEach(collection, (item) =>
{
var results = item.Calculate(parameters);
dal.Results.Insert(results);
allResults.AddRange(results);
});
在Insert方法中,它如下所示:
public override void Insert(IEnumerable<Result> entities)
{
using (var connection = GetConnection())
{
connection.Open();
using (var transaction = connection.BeginTransaction(IsolationLevel.ReadCommitted))
{
connection.Insert(entities, transaction);
transaction.Commit();
}
}
}
公共覆盖无效插入(IEnumerable实体)
{
使用(var connection=GetConnection())
{
connection.Open();
使用(var事务=connection.BeginTransaction(IsolationLevel.ReadCommitted))
{
连接。插入(实体、交易);
Commit();
}
}
}
关于代码的其他一些事情我认为不会影响这一点,但可能与此相关:
只是一个存储库,其中包含dal.Results
方法,并使用连接字符串进行预初始化,该字符串用于在每次调用Insert()
时实例化一个GetConnection()
新的SqlConnection(connectionString)
是一个allResults
,我用它来存储所有结果,以便以后在ConcurrentBag
Parallel之外使用。ForEach
- 我之所以使用事务,是因为它似乎以这种方式执行得更好,但如果这可能导致问题,我愿意接受建议
提前感谢您对此问题的指导 并行执行严重受限于IO的db操作没有任何好处 您应该创建更大的数据束,以便插入最少数量的数据库事务。这可以通过以下几种方式实现:
- 使用.NET framework提供的操作
- 通过使用专门用于高速批量操作的
- 通过构造以数据数组为参数的sql存储过程。有关表值参数的更多信息,请参见
所以请尝试以下操作:在并行循环中执行CPU密集型计算,并在循环后将所有结果保存到数据库中。您不应该创建一个连接并重用它吗?说交易表现更好对我来说是不对的。我建议单独进行计算(可能并行),然后使用Bulk-Insert插入所有记录。为本质上是I/O绑定的东西旋转线程是浪费时间thread@user3185569我读到的所有内容都说在每次调用DB时创建一个新的SqlConnection,.NET将处理连接池,等等。这不正确吗?@Slope尝试将所有记录的Db插入移动到并行之外。我几乎可以肯定它会更好,并且会解决您的问题。@所以您的问题是如何使用C#将大量记录插入SQL server表中。。我认为解决这个问题的办法不是使用并行。