1 //--------------------------------------------------------------------------
3 // Copyright (c) Microsoft Corporation. All rights reserved.
5 // File: ThreadSafeRandom.cs
7 //--------------------------------------------------------------------------
10 using System.Security.Cryptography;
12 namespace System.Threading
15 /// Represents a thread-safe, pseudo-random number generator.
17 public class ThreadSafeRandom : Random
19 /// <summary>Seed provider.</summary>
20 private static readonly RNGCryptoServiceProvider _global = new RNGCryptoServiceProvider();
21 /// <summary>The underlyin provider of randomness, one instance per thread, initialized with _global.</summary>
22 private ThreadLocal<Random> _local = new ThreadLocal<Random>(() =>
24 var buffer = new byte[4];
25 _global.GetBytes(buffer); // RNGCryptoServiceProvider is thread-safe for use in this manner
26 return new Random(BitConverter.ToInt32(buffer, 0));
29 /// <summary>Returns a nonnegative random number.</summary>
30 /// <returns>A 32-bit signed integer greater than or equal to zero and less than MaxValue.</returns>
31 public override int Next()
33 return _local.Value.Next();
36 /// <summary>Returns a nonnegative random number less than the specified maximum.</summary>
37 /// <param name="maxValue">
38 /// The exclusive upper bound of the random number to be generated. maxValue must be greater than or equal to zero.
41 /// A 32-bit signed integer greater than or equal to zero, and less than maxValue;
42 /// that is, the range of return values ordinarily includes zero but not maxValue. However,
43 /// if maxValue equals zero, maxValue is returned.
45 public override int Next(int maxValue)
47 return _local.Value.Next(maxValue);
50 /// <summary>Returns a random number within a specified range.</summary>
51 /// <param name="minValue">The inclusive lower bound of the random number returned.</param>
52 /// <param name="maxValue">The exclusive upper bound of the random number returned. maxValue must be greater than or equal to minValue.</param>
54 /// A 32-bit signed integer greater than or equal to minValue and less than maxValue;
55 /// that is, the range of return values includes minValue but not maxValue.
56 /// If minValue equals maxValue, minValue is returned.
58 public override int Next(int minValue, int maxValue)
60 return _local.Value.Next(minValue, maxValue);
63 /// <summary>Returns a random number between 0.0 and 1.0.</summary>
64 /// <returns>A double-precision floating point number greater than or equal to 0.0, and less than 1.0.</returns>
65 public override double NextDouble()
67 return _local.Value.NextDouble();
70 /// <summary>Fills the elements of a specified array of bytes with random numbers.</summary>
71 /// <param name="buffer">An array of bytes to contain random numbers.</param>
72 public override void NextBytes(byte[] buffer)
74 _local.Value.NextBytes(buffer);