TPL数据流线程本地数据 [英] TPL Data Flow Thread Local Data

查看:169
本文介绍了TPL数据流线程本地数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有传递线程本地数据转换成ActionBlock,一个很好的方法,例如,如果你在它的DataFlowExecutionOptions指定MaxDegreeOfParallelization是> 1,那么每一个执行行动任务都会有自己的线程本地数据?

下面是我的一些code,它也许会澄清我想要做的:

  VAR选项=新ExecutionDataflowBlockOptions()
     {
        MaxDegreeOfParallelism = 12
     };

ActionBlock< INT> actionBlock =新ActionBlock< INT>(的performAction,期权);

名单< INT> resultsList =新的名单,其中,INT>();

的performAction无效(int i)以
{
    //做一些工作

    //将它们添加到resultsList

    //我想请确保执行该方法的每个线程都有
    // resultsList的自己的副本
}
 

我希望能够有ActionBlock调用线程本地初始化函数我公司供应的。事情是这样的:

 新ActionBlock< INT>(的performAction,期权,()=>新建名单,其中,INT>());
 

和有它通过我的线程本地数据到我的动作功能:

 的performAction无效(INT I,名单,其中,INT> localUserData){...}
 

解决方案

我还是不明白,为什么你需要在一个数据流块线程本地列表。你说得对,TDF不具有线程本地值的任何明确的支持(顺便 Parallel.ForEach()一样)。但是,这并不意味着你不能使用线程局部变量的值,你就必须手工做的一切,用的 的ThreadLocal (我认为 [ThreadStatic] 将无法正常工作在这里,因为它不会让您跟踪的所有线程本地实例)。例如:

 私有静态的ThreadLocal<列表< INT>> threadLocalList;

私有静态无效的主要()
{
    threadLocalList =新的ThreadLocal<列表< INT>>(()=>新建名单,其中,INT>(),TRUE);

    VAR块=新ActionBlock< INT>(
        (动作< INT>)的performAction,
        新ExecutionDataflowBlockOptions {MaxDegreeOfParallelism = 4});

    的for(int i = 0;我小于10;我++)
        block.Post(ⅰ);

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

    的foreach(在threadLocalList.Values​​ VAR名单)
        Console.WriteLine(的string.join(,,列表));

    threadLocalList.Dispose();
}

私有静态无效的performAction(int i)以
{
    threadLocalList.Value.Add(I * I);
}
 

Is there a good way to pass thread local data into an ActionBlock, such that if you specify MaxDegreeOfParallelization in its DataFlowExecutionOptions to be > 1, then each task that executes the action will have its own thread local data?

Here is some of my code that will perhaps clarify what I want to do:

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 
}

I want to be able to have the ActionBlock call a thread local init function that I supply. Something like this:

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

And have it pass my thread local data into my Action function:

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

解决方案

I still don't understand why do you need thread-local list in a dataflow block. And you're right that TDF doesn't have any explicit support for thread-local values (the way Parallel.ForEach() does). But that doesn't mean you can't use thread-local values, you'll just have to do everything manually, using ThreadLocal (I think [ThreadStatic] wouldn't work well here, because it doesn't allow you to track all thread-local instances). For example:

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

这篇关于TPL数据流线程本地数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆