Random Number Generation - Same Number returned [duplicate]

Possible Duplicates:
c# - getting the same random number repeatedly
Random number generator not working the way I had planned (C#)

I have a method that builds a queue of ints:

public Queue<int> generateTrainingInts(int count = 60)
    {
        Queue<int> retval = new Queue<int>();

        for (int i = 0; i < count; i++)
        {
            retval.Enqueue(JE_Rand.rInt(2001, 100));
        }

        return retval;
    }

JE_Rand.rInt() is just a function that delegates to a function of the Random class:

public static int rInt(int exclUB, int incLB = 0)
    {
        Random rand = new Random(DateTime.Now.Millisecond);
        int t = rand.Next(incLB, exclUB);
        rand = null;            
        return t;
    }

But when I call generateTrainingInts, the same number is enqueued each time. However, if I change rInt to use a static instance of the Random class, instead of a local instance (with function scope as it is defined above), then it appears to work correctly (enqueue random integers). Does anybody know why this happens?

Edit: Dear Answerers who didn't read my question thoroughly, Like some of you pointed out, I am looking for a good explanation of why this happens. I am not looking for a solution to the same-number-generated problem, because I already fixed that like I said above. Thanks for your enthusiasm though :) I really just want to understand things like this, because my first implementation made more sense conceptually to me.


Solution 1:

You need to keep the same Random object. Put it outside your static method as a static member

private static Random rand = new Random();

public static int rInt(int exclUB, int incLB = 0)
{
    int t = rand.Next(incLB, exclUB);
    return t;
}

Edit
The reason is the finite resolution of the clock used to initialize Random. Subsequent initializations of Random will get the same starting position in the random sequence. When reusing the same Random the next value in the random sequence is always generated.

Solution 2:

Try out the following code and I think you'll see why:

void PrintNowAHundredTimes()
{
    for (int i = 0; i < 100; ++i)
    {
        Console.WriteLine(DateTime.Now);
    }
}

The Random objects are getting the same seed over and over. This is because the granularity of the system time returned by DateTime.Now is, quite simply, finite. On my machine for example the value only changes every ~15 ms. So consecutive calls within that time period return the same time.

And as I suspect you already know, two Random objects initialized with the same seed value will generate identical random sequences. (That's why it's called pseudorandom, technically.)

You should also be aware that even if it made sense to instantiate a new Random object locally within your method, setting it to null would still serve no purpose (once the method exits there will be no more references to the object anyway, so it will be garbage collected regardless).

Solution 3:

public class JE_Rand
{
   private static Random rand= new Random(DateTime.Now.Millisecond);

    public static int rInt(int exclUB, int incLB = 0)
    {
        int t = rand.Next(incLB, exclUB);
        return t;
    }
}