更新 .net 4.5 后发生堆栈溢出异常

Stack Overflow exception after update .net 4.5

有人可以帮助我吗?我快疯了:

以下代码在将 .net 更新到 4.5.2 后给我 Whosebugexception

private string CalculateStringOrder(Page p, string s)
{
    string res = null;
    char pad = '0';
    try
    {
        if (!String.IsNullOrEmpty(s))
        {

            **THIS GO IN STACK OVERFLOW**
            res = p.ItemOrder.ToString().PadLeft(5, pad) + "." + s;

        }
        else
            res = p.ItemOrder.ToString().PadLeft(5, pad);

        _pagina = p;

        if (_pagina.Parent == null)
            return res;
        while (_pagina.Parent != null)
        {
            res = CalculateStringOrder(_pagina.Parent, res);
        }
        //res = _stringOrder;
    }
    catch (WhosebugException ex)
    { }
    return res;
}

我已经尝试卸载更新清理所有引用,但错误仍然存​​在。它一直有效。

@更新

这是堆栈跟踪:

BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
BusinessLogic.dll!BusinessLogic.Page.CalculateStringOrder(BusinessLogic.Page p, string s) Riga 52   C#
>   BusinessLogic.dll!BusinessLogic.Page.StringOrder.get() Riga 29  C#
  BusinessLogic.dll!BusinessLogic.PageService.GetParentsTree.AnonymousMethod__2(BusinessLogic.Page x) Riga 40   C#
[Codice esterno]    
BusinessLogic.dll!BusinessLogic.PageService.GetParentsTree() Riga 40    C#
adico.dll!adico.Manager.Topics.Topics() Riga 21 C#
[Codice esterno]    

在您的 Page.Parent.Parent.Parent.etc 中,您有一个 循环引用

例如p.Parent = p;p.Parent.Parent.Parent = p;

这在您指定的行上给出了堆栈溢出异常,但这是来自调试器的一个红色鲱鱼。

var p = new Page { ItemOrder = "a" };
p.Parent = p;

Console.WriteLine(CalculateStringOrder(p, "xx"));

一个解决方案是记录您已经处理了哪些页面,例如:

var processed = new List<Page>();
...
if (processed.Contains(p)) return res;  // or throw an exception
processed.Add(p);

我假设这段代码试图收集 ItemOrder 对象的 Page 值,从树或路径的底部开始,一直到根。虽然代码有问题,但如果路径中有任何圆圈,即路径 A -> B -> C-> A 将导致无限递归。发生这种情况时,代码会尝试捕获不可避免的 WhosebugException 和 return 垃圾。

事实上,看起来有人试图混合递归 基于循环的代码来生成此路径。

如果生成路径的代码与生成字符串的代码分开,则更容易修复代码。以下代码按照@freedomn-m 的建议保留了访问过的页面列表:

private static Stack<Page> PathToTopRec(Page p, Stack<Page> visited=null )
{
    visited = visited ?? new Stack<Page>();
    if (visited.Contains(p))
        return visited;

    visited.Push(p);
    if (p.Parent == null)
        return visited;
    return PathToTopRec(p.Parent, visited);
}

此方法将 return 所有父页面按从根到叶的顺序排列。然后您可以生成路径字符串:

    private static string CalculateStringOrder(Page p)
    {
        var path = PathToTopRec(p);

        var builder=new StringBuilder();
        foreach (var p in path)
        {
            builder.AppendFormat("{0:0000}.",p.ItemOrder);
        }
        builder.Remove(builder.Length- 1, 1);
        return builder.ToString();
    }

新方法将 return 00001.00002.00003 用于以下数据:

    var p3 = new Page { ItemOrder = 3 };            
    var p2 = new Page { ItemOrder = 2 };
    var p1 = new Page { ItemOrder = 1 };
    p3.Parent = p2;
    p2.Parent = p1;
    var result=CalculateStringOrder(p3)

另一种选择是使用循环或递归:

    private static IEnumerable<Page> PathToTop(Page p)
    {
        var visited = new List<Page>();
        var current = p;
        while (current != null)
        {
            yield return current;
            visited.Add(current);
            current = !visited.Contains(current.Parent) 
                ? current.Parent 
                : null;
        }
    }

我正在使用迭代器,因此结果是一个 IEnumerable,其页面与 PathToTopRec 相同。对字符串生成代码的唯一更改是更改添加对 Reverse() 的调用,因为迭代器将 return 页面按照它找到它们的顺序从叶到根。

var path = PathToTop(p).Reverse();

迭代器的优点是您可以在其上应用任何 LINQ 运算符。事实上,字符串生成可以更改为:

var strings = PathToTop(p).Where(page=>page.ItemOrder>5)
                       .Select(page=>page.ItemOrder)
                       .Reverse()
                       .Select(it => string.Format("{0:0000}", it));
return String.Join(".", strings);

或 LINQ 运算符的任何其他组合。

原始代码混合了递归调用 while 循环,这表明有人曾尝试将递归代码转换为循环但放弃了。