Don't create a new instance of Random
on each iteration - that's going to seed each instance with the current time in milliseconds, which obviously isn't likely to change between iterations.
Create a single instance of Random
, and pass it into the method. I'd also advise you not to concatenate strings like that in a loop, or even to create that many strings. Additionally, if you use Random.Next(int, int)
to make your life a lot easier.
Try this:
public char GenerateChar(Random rng)
{
// 'Z' + 1 because the range is exclusive
return (char) (rng.Next('A', 'Z' + 1));
}
public string GenerateString(Random rng, int length)
{
char[] letters = new char[length];
for (int i = 0; i < length; i++)
{
letters[i] = GenerateChar(rng);
}
return new string(letters);
}
private static readonly Random SingleRandom = new Random();
public string GenerateStringNotThreadSafe(int length)
{
return GenerateString(SingleRandom, length);
}
Now it's worth being aware that Random
isn't thread-safe, so if you've got multiple threads you shouldn't just have a single instance of Random
in a static variable without locking. There are various ways around this - either create a subclass of Random
which is thread-safe, or a set of static methods which do the same thing, or use thread-local variables to have one instance per thread.
I have a StaticRandom class as part of MiscUtil but these days I'm leaning towards the thread-local version and passing it down the chain where appropriate. One day I'll add that as another option to MiscUtil...