如何检测和避免无限循环?

时间:2012-01-16 12:24:16

标签: c# asp.net performance linq infinite-loop

我想确保我的Web应用程序性能明智,不会出现任何性能问题。当我搜索时,我发现与性能问题相关的最常见问题之一是“无限循环”问题。

我想问:

我应该从哪里开始检查我的代码是否永远不会导致无限循环?

是否有任何文章,建议,说明和示例?我将不胜感激。

例如:

这个代码可能导致无限循环吗?

public static IEnumerable<SubjectNode> ReadSubjectNodes(string filePath)
{
    using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
    using (XmlReader xrdr = new XmlTextReader(fs))
        while (xrdr.Read())
            if (xrdr.NodeType == XmlNodeType.Element && xrdr.LocalName == "subject")
                yield return new SubjectNode(xrdr.GetAttribute("id"), xrdr.GetAttribute("name"), xrdr.GetAttribute("short"));
}

提前致谢

4 个答案:

答案 0 :(得分:5)

好吧,代码的AFAIK不会导致无限循环 - 它不是递归的,文件系统中的XmlReader最终会耗尽数据。但它可能长时间运行。在某些情况下,添加健全性检查可能会有所帮助 - 这可能是一个计数器,或者是对时间的检查。例如:

public static IEnumerable<SubjectNode> ReadSubjectNodes(string filePath)
{
    int safetyCheck = 10000;
    using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
    using (XmlReader xrdr = new XmlTextReader(fs))
        while (xrdr.Read()) {
            if(--safetyCheck == 0) throw new SomeTypeOfException();
            ... more code
        }
    ... more code
}

答案 1 :(得分:2)

您在此处发布的代码具有退出条件:当XmlTextReader到达其流的末尾时。因此,它不是一个无限循环。

这就是你需要做的事情来防止这些:确保每个循环都有一个条件会导致它退出。编写代码比在以后查看代码要容易得多。

答案 2 :(得分:2)

除了那些具有编译时定义的迭代次数且不改变其体内迭代计数器的循环外,无法确定性地预先确定循环是否会无限次运行。

只需编写良好代码,它不容易出现无限循环:检查while循环内的条件,并考虑一下可能导致无限循环的情况。就是这样。

答案 3 :(得分:1)

当您循环直到满足参数(while循环)时会发生Infinate循环,但是可能永远不会满足while子句退出循环。因此它会永远持续下去。

也可以引起一个递归循环,你可以从内部(或类似)调用一个函数,它会不断地调用一个函数,但是永远不会接近退出。

只要while (xrdr.Read())自动调用移动到下一个元素,

.Read()就可以了。在这种情况下,由于你的xrdr不是无限来源,它最终会到达终点并退出。