如何降低无限循环的风险?

时间:2013-04-30 16:13:39

标签: c# infinite-loop enumerator

我们正在查看我们的代码,试图识别高CPU使用率,我正在研究我们使用while循环的几个方面。我想从下面显示的代码中冒出无限循环的风险,但我不确定最佳解决方案是什么。

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;
    }
}

4 个答案:

答案 0 :(得分:5)

假设底层序列是有限的,而不是无限的,(which you have said is the case)那么循环将不会永远运行。

最终您可以确定会发生以下任何一种情况:

  1. 对于给定的项目,if将为true,从而设置布尔值并突破循环。

  2. 您将前进到序列的末尾,从而导致MoveNext为假。

  3. 将从某处抛出异常,例如来自另一个线程修改的基础集合,序列中的空值或其他任何内容。因为你没有尝试/捕获,这将使你脱离循环。

  4. 特别是,由于循环的每次迭代必须推进迭代器(由于MoveNext),你可以确定最终会结束。

答案 1 :(得分:0)

查看你的代码并试图找出你的词典实际命名的内容,我认为你正在寻找这样的东西:

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];

这假定您的词典是Error_Codes和Error_Messages。

正如Eric在评论中指出的那样,你使用迭代器和字典的方式存在问题。这消除了迭代器问题,但这仍然不是使用字典的理想方式。

如果您有一个唯一的错误消息和错误代码键列表,那么您可以使用一个字典将两者映射在一起。或者,您可以将字典与字典键的公用键集以及错误代码和错误消息组合作为字典值进行组合。

答案 2 :(得分:-1)

如果循环时间超过x时间,您可以启动一个定时器/其他线程,将第二个条件设置为false。但我不认为这是一个干净的解决方案。

答案 3 :(得分:-2)

您可以添加一个在while循环中倒计时的计数器。将计数器实数高设置为大约100左右的值,当计数器达到零时,退出循环。这意味着它可能在操作完全执行之前终止,但这意味着它最终会退出。