i have the following code inside a static method in a static class
Random r = new Random();
int randomNumber = r.Next(1,100);
i have this inside a loop and i keep getting the same randomNumber?
any suggestions here?
i have the following code inside a static method in a static class
Random r = new Random();
int randomNumber = r.Next(1,100);
i have this inside a loop and i keep getting the same randomNumber?
any suggestions here?
You should not create a new Random
instance in a loop. Try something like:
var rnd = new Random();
for(int i = 0; i < 100; ++i)
Console.WriteLine(rnd.Next(1, 100));
The sequence of random numbers generated by a single Random
instance is supposed to be uniformly distributed. By creating a new Random
instance for every random number in quick successions, you are likely to seed them with identical values and have them generate identical random numbers. Of course, in this case, the generated sequence will be far from uniform distribution.
For the sake of completeness, if you really need to reseed a Random
, you'll create a new instance of Random
with the new seed:
rnd = new Random(newSeed);
public static Random rand = new Random(); // this happens once, and will be great at preventing duplicates
Note, this is not to be used for cryptographic purposes.
Generally the best idea is to have a single instance of Random
per thread - you don't want to create an instance regularly as you'll end up with repeats as you've seen, and you don't want to reuse instances between threads as Random
isn't thread-safe.
Here's a little class to help with that:
using System;
using System.Threading;
public static class RandomHelper
{
private static int seedCounter = new Random().Next();
[ThreadStatic]
private static Random rng;
public static Random Instance
{
get
{
if (rng == null)
{
int seed = Interlocked.Increment(ref seedCounter);
rng = new Random(seed);
}
return rng;
}
}
}
You can then safely use RandomHelper.Instance
from any thread. Ideally, for testability, you should try to use this relatively rarely - treat randomness as a dependency, and pass the Random
reference into methods that need it.
Note that:
rng
field has the [ThreadStatic]
attribute applied to it, so it's effectively a different variable for each thread.seedCounter
(once) based on the current time, but then increment it in a thread-safe manner each time we need a new instance for another thread.