TheJediCowboy
TheJediCowboy

Reputation: 9222

How do I mitigate the risk of an infinite loop?

We are looking through our code trying to identify high CPU usage, and I am looking at several areas where we use while loops. I would like to take the risk of infinite loops out of the code shown below, but I am not sure what the best solution would be.

IDictionaryEnumerator codeEnumerator = Resources.Error_Codes.ResourceManager.GetResourceSet(CultureInfo.CurrentCulture, true, true).GetEnumerator();
IDictionaryEnumerator messageEnumerator = Resources.Error_Messages.ResourceManager.GetResourceSet(CultureInfo.CurrentCulture, true, true).GetEnumerator();


bool codeDone = false;
bool messageDone = false;

while (codeEnumerator.MoveNext() && !codeDone)
{
    string value = codeEnumerator.Value.ToString();
    if (value == failedResponse.Code.ToString())
    {
        key = codeEnumerator.Key.ToString();
        codeDone = true;
    }
}

while (messageEnumerator.MoveNext() && !messageDone)
{
    if (messageEnumerator.Key.ToString() == key)
    {
        message = messageEnumerator.Value.ToString();
        messageDone = true;
    }
}

Upvotes: 0

Views: 418

Answers (4)

Chris
Chris

Reputation: 707

Looking at your code and trying to figure out what your dictionaries are actually named, I think you're looking for something like this:

var key = Error_Codes.FirstOrDefault(kvp => kvp.Value.ToString = 
    failedResponse.Code.ToString()).Select(kvp => kvp.Key);
string message = string.Empty;
if(null != key)
    message = Error_Messages[key];

This assumes your dictionaries are Error_Codes and Error_Messages.

As Eric pointed out in the comments, there were issues with the way you were using iterators and dictionaries. This does away with the iterator problems, but this still isn't an ideal way to use dictionaries.

If you have a unique list of error messages and error code keys, then you could have a dictionary that maps the two together. Alternatively, you could combine the dictionaries with a common key set for the dictionary key, and a tuple of error codes and error messages as the dictionary values.

Upvotes: 0

Servy
Servy

Reputation: 203821

Assuming that the underlying sequence are finite, not infinite, (which you have said is the case) then the loops will not run forever.

Eventually you can be sure that one of the following things will happen:

  1. The if will be true for a given item, thus setting the boolean and breaking out of the loop.

  2. You will advance to the end of the sequence, thus resulting in MoveNext being false.

  3. An exception will be thrown from somewhere, such as from the underlying collection being modified by another thread, by a null value in the sequence, or anything else. As you have no try/catch, this will break you out of the loop.

In particular, since each iteration of the loop must advance the iterator (due to MoveNext) you can be sure that you will eventually end.

Upvotes: 5

Frederik Terstappen
Frederik Terstappen

Reputation: 82

You could start a timer/other thread that sets a second contidion to false if the loop takes more than x time. But i dont think that this is a clean solution either.

Upvotes: -1

shieldgenerator7
shieldgenerator7

Reputation: 1736

You could add a counter that counts down in the while loop. Set the counter real high to a value like 100 or so and When the counter reaches zero, exit the loop. It means that its possible it might terminate before the operation is completely carried out, but it means it will eventually exit.

Upvotes: -2

Related Questions