1

我在一个循环中从任务工厂创建了 x 个任务。当我等待所有任务完成时,这些任务会开始并做一些工作。

我的问题是每个任务/线程都初始化自己的昂贵对象的副本,例如 DocumentObject。理想情况下,我希望为每个任务/线程重新使用这个对象,这样当它作为工厂的一部分重新使用时,就不需要重新创建了。

ThreadLocal.Net 中的概念是否可以实现类似的事情。

4

2 回答 2

5

您不应该ThreadLocal与并行任务一起使用,如果您有需要处理的资源,除非您在创建它们时跟踪您创建的对象,否则您很难自行清理。这是因为任务是在 ThreadPool 上创建的,因此无法保证再次回到同一个线程上进行清理工作1

处理这个问题的更好方法是使用或者Parallel.For接受Parallel.ForEach一个lambada,它创建一个与任务相关联的对象,并且一次只由一个线程使用(命名为localInitand localFinally)。

Parallel.ForEach(GetSomeData(), () => new DocumentObject(),
    (sourceData, loopState, localData)
    {
        //localData is the DocumentObject that unique per thread.

        //...

        return localData; //Passes the class to the next task that is going to use it.
    }
    (localData) => 
    {
        localData.Dispose(); //Do any work here you need to do when a thread is done with the object.
    }

当然,如果您没有任何工作要做,localFinally请继续使用ThreadLocal,如果您愿意的话。


1:新到 4.5 他们添加了Values能够再次访问对象的属性,而无需在创建对象时对其进行跟踪。

于 2014-01-24T17:28:25.810 回答
0

一些想法:

  1. 在主流程中实例化您的副本ExpensiveObject,然后让您的任务访问主副本(根据需要通过值或引用)
  2. 为您的使用静态类ExpensiveObject
于 2014-01-24T17:28:26.767 回答