Передача данных о состоянии в Parallel.ForEach без использования анонимных делегатов - PullRequest
3 голосов
/ 04 августа 2011

Если у меня есть такой 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 Ответ

2 голосов
/ 04 августа 2011

Краткий ответ: вызовите его из анонимного метода.
Вы можете передать свое дополнительное состояние как отдельный параметр от анонимного метода.

Например:

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
    }
}

Длинный ответ: создайте отдельный класс, содержащий состояние, и поместите метод в этот класс.Затем вы можете передать метод экземпляра, и он получит доступ к состоянию из класса, в котором оно хранится.
Вот как скомпилированы анонимные методы.

Более подробное объяснение см. мой блог .

...