All files
[pithos-ms-client] / trunk / Libraries / ParallelExtensionsExtras / CoordinationDataStructures / ThreadSafeRandom.cs
1 //--------------------------------------------------------------------------
2 // 
3 //  Copyright (c) Microsoft Corporation.  All rights reserved. 
4 // 
5 //  File: ThreadSafeRandom.cs
6 //
7 //--------------------------------------------------------------------------
8
9 using System;
10 using System.Security.Cryptography;
11
12 namespace System.Threading
13 {
14     /// <summary>
15     /// Represents a thread-safe, pseudo-random number generator.
16     /// </summary>
17     public class ThreadSafeRandom : Random
18     {
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>(() =>
23         {
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));
27         });
28
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()
32         {
33             return _local.Value.Next();
34         }
35
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. 
39         /// </param>
40         /// <returns>
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.
44         /// </returns>
45         public override int Next(int maxValue)
46         {
47             return _local.Value.Next(maxValue);
48         }
49
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>
53         /// <returns>
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.
57         /// </returns>
58         public override int Next(int minValue, int maxValue)
59         {
60             return _local.Value.Next(minValue, maxValue);
61         }
62
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()
66         {
67             return _local.Value.NextDouble();
68         }
69
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)
73         {
74             _local.Value.NextBytes(buffer);
75         }
76     }
77 }