是否有一种将线程本地数据传递到ActionBlock的好方法,这样如果在其DataFlowExecutionOptions中指定MaxDegreeOfParallelization为> 1,那么执行该操作的每个任务都有自己的线程本地数据?
以下是我的一些代码,可能会澄清我想要做的事情:
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) {...}
答案 0 :(得分: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);
}