The Problem

There are often questions on .NET newsgroups such as: "Why am I getting the same numbers out of Random time and time again?" When the code involved is posted, it's almost always something like the following:

using System;

class Program
{
    static void Main(string[] args)
    {
        for (int i=0; i < 100; i++)
        {
            Console.WriteLine (GenerateRandomNumber());
        }        
    }
    
    static int GenerateRandomNumber()
    {
        // Bad code! Do not use!
        Random rng = new Random();
        return rng.Next();
    }
}

So, what's wrong with it? Well, when you create an instance of Random, it uses a seed to work out where to start. If you use the same seed value twice, you'll get the same sequence of random numbers. When you use the parameterless constructor (as tends to be the case), Random uses the current time as the seed. The code above creates several instances in very quick succession, and "the current time" tends to have a granularity of at least 10ms, so many instances will share the same seed and thus create the same sequence of numbers.

The Solution

The usual answer is to create a single instance of Random and reuse it. That's all very well, but it can be a bit unsightly - you end up with one instance of Random per class which needs to use random numbers, when you really only want a system-wide one. Using a static member somewhere would seem an obvious answer, but Random isn't thread-safe. My suggested solution is to use MiscUtil.StaticRandom, which is a class composed entirely of static methods mirroring the ones in System.Random. Using it is very simple:

using System;
using MiscUtil;

class Program
{
    static void Main(string[] args)
    {
        for (int i=0; i < 100; i++)
        {
            Console.WriteLine (StaticRandom.Next());
        }        
    }
}

(The call to Next() can be replaced with NextDouble(), NextBytes() etc. Thread safety is achieved with a simple lock - I experimented with a thread-local instance of Random, but found it to be slower than using a lock.

Enjoy!


Back to the main MiscUtil page.