Paralel System.Random

Paralel uygulamalarda çeşitli yerlerde rastgeleliğe ihtiyaç duyabiliriz. Rastgeleliğin, şifreleme seviyesinde güçlü olmasının gerekmediği durumlarda System.Random kullanmak hızlı ve iyi bir seçimdir, fakat paralel kullanımlarda çok iyi sonuçlar vermez. Bu gibi durumlarda aşağıdaki sınıf kullanılabilir.

using System;
using System.Collections;
using System.Collections.Generic;

namespace Core.Utilities
{
    /// <summary>Parallel safe version of System.Random</summary>
    public static class RandomGen
    {
        private static readonly Random Global = new Random();

        [ThreadStatic]
        private static Random _local;

        /// <summary>Returns a nonnegative random number.</summary>
        public static int Next()
        {
            var inst = _local;

            if (inst == null)
            {
                int seed;

                lock (Global) seed = Global.Next();

                _local = inst = new Random(seed);
            }

            return inst.Next();
        }

        /// <summary>Returns a nonnegative random number less than the specified minimum.</summary>
        public static int Next(int maxValue)
        {
            var inst = _local;

            if (inst == null)
            {
                int seed;

                lock (Global) seed = Global.Next();

                _local = inst = new Random(seed);
            }

            return inst.Next(maxValue);
        }

        /// <summary>Returns a random number within a specified range.</summary>
        public static int Next(int minValue, int maxValue)
        {
            var inst = _local;

            if (inst == null)
            {
                int seed;

                lock (Global) seed = Global.Next();

                _local = inst = new Random(seed);
            }

            return inst.Next(minValue, maxValue);
        }

        /// <summary>Returns a random element from a list.</summary>
        public static T Next<T>(IList<T> list)
        {
            var inst = _local;

            if (inst == null)
            {
                int seed;

                lock (Global) seed = Global.Next();

                _local = inst = new Random(seed);
            }

            return list[inst.Next(0, list.Count)];
        }

        /// <summary>Returns a random number between 0.0 and 1.0.</summary>
        public static double NextDouble()
        {
            var inst = _local;

            if (inst == null)
            {
                int seed;

                lock (Global) seed = Global.Next();

                _local = inst = new Random(seed);
            }

            return inst.NextDouble();
        }

        /// <summary>Fills the elements of a specified array of bytes with random numbers.</summary>
        public static void NextBytes(byte[] buffer)
        {
            var inst = _local;

            if (inst == null)
            {
                int seed;

                lock (Global) seed = Global.Next();

                _local = inst = new Random(seed);
            }

            inst.NextBytes(buffer);
        }
    }
}