title: Create ThreadLocal random generators with known seeds
body: <p>I'm struggling to find a way to have a single random number generator per thread, while at the same time making sure that when the program is re-run, the same numbers are produced.</p>
  
  <p>What I do now is something like this:</p>
  
  <pre><code>class Program {
      static void Main(string[] args) {
  
          var seed = 10;
          var data = new List&lt;double&gt;();
          var dataGenerator = new Random(seed);
  
          for (int i = 0; i &lt; 10000; i++) {
              data.Add(dataGenerator.NextDouble());
          }
  
          var results = new ConcurrentBag&lt;double&gt;();
  
          Parallel.ForEach(data, (d) =&gt; {
              var result = Calculate(d, new Random(d.GetHashCode()); 
              results.Add(result);
          });
  
      }
  
      static double Calculate(double x, Random random) {
          return x * random.NextDouble();
      }
  }
  </code></pre>
  
  <p>Because the randomgenerator that creates the 'data' list is provided a seed and the randomgenerators that are used in the calculation are provided a seed based on the hashcode of the number being processed, the results are repeatable. Regardless the number of threads and the order in which they are instantiated.</p>
  
  <p>I'm wondering if it's possible to instantiate just a single randomgenerator for each thread. The following following piece of code seems to accomplish that, but because the random generators are not provided with a (reproducible) seed anymore, the results are not repeatable.</p>
  
  <pre><code>class Program {
      static void Main(string[] args) {
  
          var seed = 10;
          var data = new List&lt;double&gt;();
          var dataGenerator = new Random(seed);
  
          for (int i = 0; i &lt; 10000; i++) {
              data.Add(dataGenerator.NextDouble());
          }
  
          var results = new ConcurrentBag&lt;double&gt;();
  
          var localRandom = new ThreadLocal&lt;Random&gt;(() =&gt; new Random());
  
          Parallel.ForEach(data, (d) =&gt; {
              var result = Calculate(d, localRandom.Value); 
              results.Add(result);
          });
  
      }
  
      static double Calculate(double x, Random random) {
          return x * random.NextDouble();
      }
  }
  </code></pre>
  
  <p>Can anyone think of a nice solution to this problem?</p>