微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为每个线程声明一个变量,并在c#Parallel.Foreach中对其进行管理

如何解决为每个线程声明一个变量,并在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 举报,一经查实,本站将立刻删除。