c# - 任务工厂和线程本地存储

标签 c# multithreading task-parallel-library task thread-local-storage

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

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

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

最佳答案

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

处理此问题的更好方法是使用 Parallel.ForParallel.ForEach它接受一个 lambada,该 lambada 创建一个与任务相关的对象,并且一次仅由一个线程使用(名为 localInitlocalFinally)。

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属性,以便能够再次访问对象,而无需在创建对象时对其进行跟踪。

关于c# - 任务工厂和线程本地存储,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21338612/

相关文章:

c# - 二维数组未按预期在 C# 中创建

c# - Tuple<List<int>, List<int>> 还是 List<Tuple<int, int>>?

c# - 在 C# 中取消多个任务的正确方法是什么

java - 我对 Java 多线程的长期困惑。需要帮忙

java - 为什么在java中有两种使用线程的方式?

c# - 如何限制创建的任务数量?

c# - 您为什么要使用continueWith而不是简单地将延续代码附加到后台任务的末尾?

c# - 在 WebJobs SDK 中将 Singleton 属性与 ServiceBusTrigger 结合使用

c# - 将各种数据一起发布的最佳方式(Web API)

c++ - 关于线程的问题