将状态数据传递给Parallel.ForEach而不使用匿名委托

时间:2011-08-04 15:30:22

标签: c# .net-4.0 lambda task-parallel-library

如果我有一个这样的Parallel.ForEach,使用ForEach主循环的匿名委托:

var someState = GetSomeState();
Parallel.ForEach(MyIEnumerableSource, 
    () =>
    {
        return new DataTable();
    },
    (record, loopState, localDataTable) =>
    {
        localDataTable.Rows.Add(someState.Value, record);
        return localDataTable
    },
    (localDataTable) =>
    {
        using (var bulkInsert = new SqlBulkCopy(ConnectionString))
        {
            bulkInsert.DestinationTableName = "My_Table";
            bulkInsert.WriteToServer(localDataTable);
        }
        localDataTable.Dispose();
    });

如何将其转入以下主循环现在是一个真正的函数,但静态坐在另一个类中:

var someState = GetSomeState();
Parallel.ForEach(MyIEnumerableSource, 
    () =>
    {
        return new DataTable();
    },
    OtherClass.Process,
    (localDataTable) =>
    {
        using (var bulkInsert = new SqlBulkCopy(ConnectionString))
        {
            bulkInsert.DestinationTableName = "My_Table";
            bulkInsert.WriteToServer(localDataTable);
        }
        localDataTable.Dispose();
    });

//In another class in another file
static class OtherClass
{
    public static DataTable Process(MyRecordType record, ParallelLoopState loopState, DataTable localDataTable)
    {
        localDataTable.Rows.Add(someState.Value, record); //How to I bring over someState when it is called here?
        return localDataTable
    }
}

我如何访问在for循环之外创建的状态,而不需要成为线程本地存储的一部分?

如果这个函数不是静态的,我会使用一个实例变量,并且它位于同一个类中,但ForEach的主循环在另一个类的静态函数中,并且将在代码中的多个位置使用,所有这些都是他们自己的someState副本。

如何携带该状态变量?

1 个答案:

答案 0 :(得分:2)

简短回答:用匿名方法调用它 您可以将其他状态作为单独参数从匿名方法传递。

例如:

var someState = GetSomeState();
Parallel.ForEach(MyIEnumerableSource, 

    () => new DataTable(),

    (record, loopState, localDataTable) =>
       OtherClass.Process(record, loopState, LocalDataTable, someState),

    (localDataTable) => { ... }
);

static class OtherClass
{
    public static DataTable Process(MyRecordType record, ParallelLoopState loopState, DataTable localDataTable, someStateType someState)
    {
        localDataTable.Rows.Add(someState.Value, record);
        return localDataTable
    }
}

长答案:创建一个包含状态的单独类,并将该方法放在该类中。然后,您可以传递实例方法,并且可以从拥有它的类访问该状态 这就是匿名方法的编译方式。

有关更详尽的说明,请参阅my blog