Link to home
Start Free TrialLog in
Avatar of matticus
matticus

asked on

simple C# method to generate string of random words returns unexpected results

Hello,

I have a simple method that opens a text file with a list of 10,000 words and generates a random string from those words. Here is the method:

        private string GetWords()
        {
            string sentence = "";

                StreamReader r;

                for (int y = 0; y < 10; y++)
                {
                    r = File.OpenText("C:\\words.txt");

                    Random rand = new Random();
                    int next = rand.Next(1,10000);

                    for (int x = 0; x < next; x++)
                    {
                        r.ReadLine();
                    }

                    sentence += r.ReadLine() + " ";

                    // MessageBox.Show(sentence);
                }

                return sentence;
        }

For some reason, the strings this method returns look like this:

       CAR CAR CAR CAR CAR TIGER TIGER ROOSTER ROOSTER ROOSTER

If I insert the statement MessageBox.Show(sentence) after each iteration of the second loop, however, the string returne is exactly what I would expect; something like:

       CAR APPLE DOG ZEBRA LION BEAR TIGER EMU ROOSTER FOX

This may be an utterly simple oversight, but I have gone over and over the logic and cannot seem to figure out why I am getting unexpected return values like in the first example.

Any ideas would be greatly appreciated.

Thanks ahead of time,
Matt
Avatar of kojoru
kojoru
Flag of Russian Federation image

That happens because of timer randomization. Random changes the data it generates every millisecond, so you need to sleep for 1 ms every loop iteration. To do this execute the following before Random rand = new Random();

System.Threading.Thread.Sleep(1);

Open in new window

Avatar of matticus
matticus

ASKER

Adding System.Threading.Thread.Sleep(1); did not change the behavior. Interesting suggestion, however. Maybe something else along those lines?
I increased the value to 50ms and it seems to have begun generating randoms. Thanks for your help, kojoru. I will play around with this.
Increasing would have been my next suggestion :-)
The values have indeed become less repetitve, however this is causing a significant performance hit. Is there a different way of generating the random number?
SOLUTION
Avatar of philipjonathan
philipjonathan
Flag of New Zealand image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Here is a sample program that illustrates it all

using System;
using System.Collections.Generic;
using System.Text;
 
namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("New Random every iteration");
            for (int i = 0; i < 10; i++)
            {
                Random rnd = new Random();
                Console.Write(""+rnd.Next(10000)+" ");
            }
            Console.WriteLine("\nSame with 1 ms sleep");
            for (int i = 0; i < 10; i++)
            {
                Random rnd = new Random();
                System.Threading.Thread.Sleep(1);
                Console.Write("" + rnd.Next(10000) + " ");
            }
            Console.WriteLine("\nSleep time is 20 ms:");
            for (int i = 0; i < 10; i++)
            {
                Random rnd = new Random();
                System.Threading.Thread.Sleep(20);
                Console.Write("" + rnd.Next(10000) + " ");
            }
            Console.WriteLine("\nUsing the only Random:");
            Random rnd2 = new Random();
            
            for (int i = 0; i < 10; i++)
            {
                Console.Write("" + rnd2.Next(10000) + " ");
            }
            Console.ReadLine();
 
            /*
             * Sample output:
             *  New Random every iteration
             *  2797 2797 2797 2797 2797 2797 2797 2797 2797 2797
             *  Same with 1 ms sleep
             *  1161 1161 1161 1161 1161 1161 1161 1161 4749 4749
             *  Sleep time is 20 ms:
             *  4749 8337 6701 8653 2241 5829 7781 1369 9733 1685
             *  Using the only Random:
             *  5273 4665 390 7349 26 3432 177 8825 1936 1809
             */ 
        }
    }
}

Open in new window

Moving the following line correct the problem:
    Random rand = new Random();

I have doubled the point value and split the points. Thank you both for your help.