Paladin Paladin - 2 months ago 11
C# Question

Why is the random generation and array working together if I press ENTER between each loop?

As long as I have the readkey in the code the end result is 7 different random loops (foreach). When I remove readkey I mostly get 7 identical numbers (foreach).

That led me to start experimenting with Task.Delay but it seems to make no difference. I thought it might be a timing problem as intemittently the first of the 7 random numbers would be different from the last 6.

I want the code to work in one sweep without me having to press a key. My apology if the format in this post is dodgy. I have bad experince of pressing ENTER in this input window.

int[] tray = new int[7];

for (int i = 0; i < tray.Length; i++)
{
Random rnd = new Random();
int randomNumber = rnd.Next(1, 26);
//Task.Delay(9000);
tray[i] = randomNumber;
Console.WriteLine("randomNumber {0} is {1} ENTER ", i + 1, tray[i]);
//Task.Delay(9000);
Console.ReadKey();
}
foreach (var number in tray)
{
Console.WriteLine(number);
}

Answer
  1. Task.Delay(9000) does not block. It creates a Task that is completed after (approx.) 9000ms. But you don't wait for that task to complete.
  2. The Random class does not magically generate real random numbers, but takes numbers from a pre-defined pseudo-random number list. Where in the list it starts is depends on a seed passed to its constructor. You use the default constructor which uses a timestamp as seed.
    If you don't pause in your loop (via Console.ReadKey() or Thread.Sleep(9000) instead of Task.Delay(9000)), this timestamp is probably always the same so you always get identical "random" numbers.

To avoid these problems, declare your Random outside the loop's scope, so it's initialized once and does not repeat the same numbers:

Random rnd = new Random();
for (int i = 0; i < tray.Length; i++)  
    tray[i] = rnd.Next(1, 26);

More information about pitfalls in random number generation.


And a (imo) more elegant way to generate an array of 7 random numbers:

Random rnd = new Random();
int[] tray = Enumerable.Range(0, 7).Select(i => rnd.Next(1, 26)).ToArray();