user1526912
user1526912

Reputation: 17210

While loop produce incorrect results with no breakpoints in C# program

I am having weird problem with the code below where when I exclude breakpoints from my while loop, the results are different.

The foreach loop, loops through 20 items from a list and adds each item to a dictionary.

When I add a breakpoint in the loop and skip through 20 times, 20 items are added.

If I remove all breakpoints and run the program only 1 item is added.

public void AddLinks(Dictionary<Guid,string> RowKeyTitles)
{
    var combinedUrlsList = new Dictionary<string, string>();

    var urlTemplate = ConfigurationManager.AppSettings["playlisturl"];
    var count = 0;

    foreach (var row in RowKeyTitles)
    {
        var shortUrl = StringGenerator.GenerateShortLink(4);
        var combinedUrl = urlTemplate.Replace("{name}", row.Value).Replace("{id}",row.Key.ToString());

        while (!combinedUrlsList.ContainsKey(shortUrl))
        {
            Console.WriteLine("test");

            shortUrl = StringGenerator.GenerateShortLink(4);

            if (!combinedUrlsList.ContainsKey(shortUrl))
            {
                count++; 
                Console.WriteLine("Added{0}", count);
                combinedUrlsList.Add(shortUrl, combinedUrl);

            }
        }              
    }

    Console.WriteLine("Count{0}",combinedUrlsList.Count());
    Console.ReadLine();
}

Does anyone knows what could be causing this behavior?

Upvotes: 0

Views: 183

Answers (2)

I4V
I4V

Reputation: 35353

I will make a guess and say that StringGenerator.GenerateShortLink(4); generates the same shortUrl in a tight loop. This is most probably, you are creating a new Random class in the loop.

An example for broken code

while(.....)
{
    Random rnd = new Random();
    rnd.Next();
}

This would generate many same numbers, since Random() uses system time as a seed.

To fix. declare Random as a your class's private field and create it only once.

Upvotes: 2

Yahia
Yahia

Reputation: 70369

The only possible explanation with the information given is that StringGenerator.GenerateShortLink is implemented in a way that it is "timinig-sensitive" - for example if it uses a Random instance internally and recreates it at every call... in such a case the newly created instance (by default) is initialized utilizing the current system time... with breakpoints it gets delayed enough that it produces a different random number... without breakpoints it gets initialized with the same number (because there is not enough delay) and thus produces the same random number(s) which in turn produces the same shortUrl it already produced the first time... since that is already part of the Dictionary combinedUrlsList it just won't be added a second time...

Fix for the above behaviour:
Don't recreate the Random instance used inside StringGenerator.GenerateShortLink between calls but reuse the already created instance in subsequent calls...

Upvotes: 0

Related Questions