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.