如何解决为每个线程声明一个变量,并在c#Parallel.Foreach中对其进行管理
我正在编写代码以遍历庞大的对象列表,以将其持久存储在数据库中。
每次迭代我都会增加一个计数器,当迭代次数达到500时,我将所有数据持久保存在DB中(通过StringBuilder)。
如果我按顺序执行,则不会有问题,但是需要很长时间。这就是为什么我要使用并行性。
通过并行性,我已经看到我无法为所有线程使用一个StringBuilder,因此我需要为每个线程创建一个。
我的问题是: 如何为每个线程创建StringBuilder? 然后,当静态计数器达到500个循环时,如何将所有StringBuilder对象持久保存到DB并将它们全部清空?
int counter = 0;
Parallel.ForEach(myList,element =>
{
lock (balanceLock)
{
counter++;
}
var sb = new StringBuilder(); //I need one StringBuilder for thread,not for iteration
...
if (decimal.Remainder(counter,500) == 0)
lock (balanceLock)
{
persistInDB(sb.toString());
sb.Clear();
}
});
解决方法
最后,我按照建议的顺序解决了这一问题,方法是将记录放在表中,并根据建议对数据库进行SqlBulkCopy。
DataTable table = getDataTable();
myList.ForEach(element => {
//...
table.Rows.Add(getRow(element));
if (decimal.Remainder(counter,500) == 0){
SqlConnection _db;
_db.Open();
using (SqlBulkCopy bulk = new SqlBulkCopy(_db)){
var map1 = new SqlBulkCopyColumnMapping("columnName1","columnName1");
var map2 = new SqlBulkCopyColumnMapping("columnName2","columnName2");
//...
bulk.ColumnMappings.Add(map1);
bulk.ColumnMappings.Add(map2);
//...
bulk.DestinationTableName = "DestinationTableName";
bulk.WriteToServer(table);
bulk.Close();
}
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。