Question

I create x number of Tasks from the Task Factory in a loop. These tasks go off and do some work while I wait on all tasks to finish.

The question I have is that each task/thread initializes its own copy of an expensive object say DocumentObject. I would ideally like to re-use this object for each Task/Thread so that when it is re-used as part of the factory there will be no need to re-create.

Is something like this possible with theThreadLocalconcept in .Net.

Was it helpful?

Solution

You should not use ThreadLocal with parallel Tasks, it is very hard to clean up after yourself if you have resources that need disposing unless you track the objects you create as you create them. This is because Tasks are created on the ThreadPool so there is no way to guarantee to get back on the same thread again to do your cleanup work1.

A better way to handle this is use either Parallel.For or Parallel.ForEach that takes in a lambada that creates a object that is tied to the task and is only used by one thread at a time (named localInit and 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.
    }

Of course if you don't have any work to do in localFinally go ahead and use ThreadLocal if you want to.


1: New to 4.5 they added the Values property to be able to get access to the objects again without needing to track them as you create them.

OTHER TIPS

Some ideas:

  1. Instantiate a copy of your ExpensiveObject in the main process, and then have your tasks access the main copy (by value or reference, as desired)
  2. Use a static class for your ExpensiveObject
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top