]> C# Duplicate random numbers 🌐:aligrant.com

C# Duplicate random numbers

Alastair Grant | Tue 15 Jul 2014

A bug came about in testing, where there was multiple items to process things fell apart due to duplication - which is strange, as I had thought of that and generated, what I thought, was a random enough number to keep things unique.

The problem appears to be around how the standard .NET random number generator works in a multi-threaded, parallel environment. Take this bit of code for instance:

Parallel.For(0, 10, i => {
   Random rnd = new Random();
   Console.WriteLine("{0}: {1}", i, rnd.NextDouble());

When you run this, there is a good chance that most, if not all (especially if you add formatting) will come back with the same number.

I assume the issue comes from how random numbers are generated - I don't know how it works in Windows, but in a Linux environment there is a system random number generator, which you can access via /dev/random. If there isn't enough randomness available your code will hang until something is returned. To avoid this, you can use /dev/urandom, which returns immediately - but this reuses what it had before. I guess something similar is going on with the .NET Random class and as each thread has it's own instance, the class is unaware that it may need to mix things up a little.

The general solution is to use a single instance of the Random class and access it across all threads. This though isn't always a feasible option. What you can do though is seed the number generator with yet another random input, which so far seems to be reliable:

Random rnd = new Random(Guid.NewGuid().GetHashCode());

This uses the GUID generator, which should create a globally unique ID, and pull out the "hash code", this is a number that is used internally by things like hashtables for sorting etc. As the hash code is an integer - you honestly could probably just use this instead of Random, depending on how you require your numbers to be returned (e.g. bytes etc).

Breaking from the voyeuristic norms of the Internet, any comments can be made in private by contacting me.