dimanche 30 octobre 2016

Is it a good/bad idea to keep ThreadLocal between parallel loops?

I'm trying to use ThreadLocal for parallel random generators. My test code is something like this:

class Program
{
    static void Main()
    {
        using (MyClass myClass = new MyClass())
        {
            for (int i = 0; i < 3; i++)
            {
                Console.WriteLine("\nPass {0}: ", i + 1);
                myClass.Execute();
            } 
        }

        Console.WriteLine("\nPress any key...");
        Console.ReadKey();
    }
}

sealed class MyClass : IDisposable
{
    ThreadLocal<RandomGenerator> threadRNG = new ThreadLocal<RandomGenerator>(() => 
                                                    new RandomGenerator());

    public void Execute()
    {
        Action<int> action = (i) =>
        {
            bool repeat = threadRNG.IsValueCreated;
            List<int> ints = new List<int>();
            int length = threadRNG.Value.RNG.Next(10);
            for (int j = 0; j < length; j++)
                ints.Add(threadRNG.Value.RNG.Next(100));
            Console.WriteLine("Action {0}. ThreadId {1}{2}. Randoms({3}): {4}", 
                i + 1, threadRNG.Value.ThreadId, repeat ? " (repeat)" : "", 
                length, string.Join(", ", ints));
        };

        Parallel.For(0, 10, action);
    }

    public void Dispose()
    {
        threadRNG.Dispose();
    }
}

class RandomGenerator
{
    public int ThreadId { get { return Thread.CurrentThread.ManagedThreadId; } }
    Random rng;
    public Random RNG { get { return rng; } }
    public RandomGenerator()
    {
        rng = new Random(Guid.NewGuid().GetHashCode());
    }
}

Is it a good/bad idea to keep ThreadLocal between multiple executions of parallel loop? I'm afraid that there may accumulate unused instances of RandomGenerator. Especially when I have thousands of executions.




Aucun commentaire:

Enregistrer un commentaire