首页 > 解决方案 > c#/vb Stack Overflow Exception on相对较小的调用堆栈

问题描述

我的 VB.NET DLL 中出现堆栈溢出异常。

调用堆栈有 115 个调用深度,它不是一个有问题的递归程序,但调用堆栈的深度是真正需要的。

我想知道为什么当我想象递归程序比这更深入时它会爆炸。有谁知道是什么导致堆栈空间被用完?例如,一个长字符串作为其中一个调用中的参数是否有贡献?或者其他什么会导致它?

我试过以下

该代码目前是单线程的,并被编译为 64 位进程。

我大约一年没有升级 VS,所以不确定是什么导致了这个

我知道如何通过在不同的线程上启动部分进程然后等待它们来解决这个问题,但是这个解决方案让我担心,因为它更多的是一种解决方法/黑客,而不是首先找到导致它的原因。

因此,希望了解可能导致错误的可能因素,并思考什么可能导致堆栈空间如此迅速地填满。

我确信如果在 C# 中迁移程序会继续出错,所以我也用 C# 进行了标记,因为该错误在该语言中发生的可能性相同。

标签: c#vb.netstack-overflow

解决方案


深度将受到方法中发生的事情的影响。我创建了这个示例,它根据编译器变量 foo 获得不同的计数。当 foo 为 true 时,我得到 2799 计数,false 计数为 5364。我必须使用 #if 的定位才能看到计数。

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        test()
    End Sub

    Dim count As Integer = 0

#Const foo = True
    Private Sub test()
        Try
            count = count
            count += 1

            Dim xe As XElement = <breakfast_menu></breakfast_menu>
            xe.Add(<food>
                       <name>Belgian Waffles</name>
                       <price>$5.95</price>
                       <calories>650</calories>
                   </food>)
            xe.Add(<food>
                       <name>Strawberry Belgian Waffles</name>
                       <price>$7.95</price>
                       <calories>900</calories>
                   </food>)
#If foo Then
            xe.Add(<food>
                       <name>Berry-Berry Belgian Waffles</name>
                       <price>$8.95</price>
                       <calories>900</calories>
                   </food>)
            xe.Add(<food>
                       <name>French Toast</name>
                       <price>$4.50</price>
                       <calories>600</calories>
                   </food>)
            xe.Add(<food>
                       <name>Homestyle Breakfast</name>
                       <price>$6.95</price>
                       <calories>950</calories>
                   </food>)

            Dim ie As IEnumerable(Of XElement)
            ie = From el In xe.<food>
                 Where Integer.Parse(el.<calories>.Value) < 900
                 Select el
#End If
            test()

        Catch ex As Exception
            Stop
        End Try
    End Sub

推荐阅读