2

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);
        }
Jongware
  • 22,200
  • 8
  • 54
  • 100
Paladin
  • 119
  • 7

2 Answers2

3

This is because you are intializing the Random inside the loop. Move the declaration outside of the loop and you should get random values. like:

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

When you have the Random inside the loop, it uses system clock for seed. Without Console.ReadKey each iteration would end up using the same seed because of very less work in the iteration. Thus Random (rnd) would end up using the same seed every time. Once your introduced Console.ReadKey, that will change the seed and because of that you were seeing different result.

One more thing, is that you tried Task.Delay but you didn't see any difference. The reason is that Task.Delay doesn't block the thread, so there was no change in clock time for the next iteration. Just for the purpose of test, you can use :

Task.Delay(1000).Wait();

Or

Thread.Sleep(1000);

This will cause the thread to be blocked for almost a second and you will end up with different/random results.

Still the better approach would be to intialize Random outside the loop.

Habib
  • 219,104
  • 29
  • 407
  • 436
2
  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();
René Vogt
  • 43,056
  • 14
  • 77
  • 99
  • OK, That makes sense. But how should I go about getting 7 random numbers to populate my array if I do not put them in a loop? I tried to put the random generator in a method and calling it but have the same problem.I ended up using Thread.Sleep but I am aware that it is not a good way. Thanks for the enlightenment. – Paladin May 18 '16 at 14:45
  • @Paladin by instantiating the `rnd` only once outside the loop as I and Habib suggested. Updated my answer. – René Vogt May 18 '16 at 14:48
  • Wow that was way out of my noobness.I see how I could have looked deeper in *.Range. Thanks again I have only been at this a short while as a student. – Paladin May 18 '16 at 14:58
  • @Paladin if this solved your issue, you may mark the answer as accepted. – René Vogt May 18 '16 at 15:00
  • It is solved. Looking franticly do mark it as solved. – Paladin May 18 '16 at 15:04