为每个线程声明一个变量并在 c# 中管理它们 Parallel.Foreach

Declare a variable per thread and manage them in c# Parallel.Foreach

我正在编写代码来遍历大量对象,以便将它们保存在数据库中。

我有一个计数器,它随着每次迭代而增加,当它达到 500 时,我将所有内容都保存在数据库中(来自 StringBuilder)。

如果我按顺序做我没有问题,但需要很长时间。这就是为什么我想用并行来做。

对于并行性,我发现我不能为所有线程创建一个 StringBuilder,因此我需要为每个线程创建一个。

我的问题是: 如何为每个线程创建一个 StringBuilder? 然后,如何将所有 StringBuilder 对象持久化到 DB 并在静态计数器达到 500 循环时清空它们?

我有以下代码:

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();
        }
});

最后我按顺序解决了这个问题,方法是将记录放入 table 并根据建议对数据库进行 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();
        }
    }
}