0

DataFlowExecutionOptions で MaxDegreeOfParallelization を > 1 に指定すると、アクションを実行する各タスクが独自のスレッド ローカル データを持つように、スレッド ローカル データを ActionBlock に渡す良い方法はありますか?

これは、おそらく私がやりたいことを明確にする私のコードの一部です:

var options = new ExecutionDataflowBlockOptions() 
     {
        MaxDegreeOfParallelism = 12
     };

ActionBlock<int> actionBlock = new ActionBlock<int>(PerformAction, options);

List<int> resultsList = new List<int>();

void PerformAction(int i)
{
    // do some work

    // add them to resultsList 

    // i want to make sure that each thread that executes this method has its 
    // own copy of resultsList 
}

ActionBlock が、私が提供するスレッド ローカルの init 関数を呼び出せるようにしたいと考えています。このようなもの:

new ActionBlock<int>(PerformAction, options, () => new List<int>()); 

そして、スレッド ローカル データを Action 関数に渡します。

void PerformAction(int i, List<int> localUserData) {...}
4

1 に答える 1

2

なぜデータフロー ブロックにスレッド ローカル リストが必要なのか、まだわかりません。そして、TDF がスレッド ローカル値を明示的にサポートしていないことは確かです (方法Parallel.ForEach()はあります)。しかし、それはスレッドローカル値を使用できないという意味ではありません。すべてを手動で行う必要があります (すべてのスレッドローカル値を追跡できないため、ここではうまく機能しないThreadLocalと思います)[ThreadStatic]インスタンス)。例えば:

private static ThreadLocal<List<int>> threadLocalList;

private static void Main()
{
    threadLocalList = new ThreadLocal<List<int>>(() => new List<int>(), true);

    var block = new ActionBlock<int>(
        (Action<int>)PerformAction,
        new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 4 });

    for (int i = 0; i < 10; i++)
        block.Post(i);

    block.Complete();
    block.Completion.Wait();

    foreach (var list in threadLocalList.Values)
        Console.WriteLine(string.Join(", ", list));

    threadLocalList.Dispose();
}

private static void PerformAction(int i)
{
    threadLocalList.Value.Add(i * i);
}
于 2013-02-05T00:53:09.537 に答える