VB.net中的堆栈溢出异常
我今天在工作中对一个定期运行以处理某些数据处理需求的应用程序进行故障排除,它通常运行正常,但有时应用程序会崩溃,需要有人手动重新启动 在查看源代码并进行一些调试之后,程序的核心似乎依赖于一个递归函数,该函数从DataTable中删除行,然后在DataTable不再有任何剩余行时停止 代码如下:VB.net中的堆栈溢出异常,vb.net,Vb.net,我今天在工作中对一个定期运行以处理某些数据处理需求的应用程序进行故障排除,它通常运行正常,但有时应用程序会崩溃,需要有人手动重新启动 在查看源代码并进行一些调试之后,程序的核心似乎依赖于一个递归函数,该函数从DataTable中删除行,然后在DataTable不再有任何剩余行时停止 代码如下: Public Sub ProcessData(ByRef dtTable As DataTable) Dim DataView1 As New DataView() Dim UID As Stri
Public Sub ProcessData(ByRef dtTable As DataTable)
Dim DataView1 As New DataView()
Dim UID As String = ""
Dim dtUID As New DataTable
dtUID = dtTable.Clone()
UID = dtTable.Rows(0)("UID")
DataView1 = dtTable.DefaultView
Dim expression As String = "UID ='" & UID & "'"
DataView1.RowFilter = expression
For n As Integer = 0 To DataView1.Count - 1
dtUID.ImportRow(DataView1.Item(n).Row)
Next
Dim foundRows() As DataRow
foundRows = dtTable.Select(expression)
For n As Integer = 0 To foundRows.GetUpperBound(0)
dtTable.Rows.Remove(foundRows(n))
Next
For n As Integer = 0 To dtUID.Rows.Count - 1
ProcessRecord(dtUID, n)
Next
If dtTable.Rows.Count > 0 Then
ProcessData(dtTable)
End If
End Sub
ProcessRecord()
是一个将所有业务逻辑应用于记录并对数据库进行写入的函数。未处理的堆栈溢出异常发生在:
For n As Integer = 0 To DataView1.Count - 1
在现实世界中,此函数将提供一个数据表
,其中包含大约100000条记录。在测试过程中,经过多次试运行后,在堆栈溢出之前,它将持续运行大约40000-65000次。创建已处理的DataTable
和ProcessRecord()
标记记录的代码,因此,如果您正在处理100000条记录的大型数据集,则崩溃后对该方法的后续调用将传递一个较小的DataTable
(35000-60000条记录)有趣的是,堆栈溢出将越来越频繁地发生在较小的数据表中,我可以始终通过40k-65k的100k数据表,但无法始终通过15k数据表中的15k而不发生崩溃(最终它将完成所有记录,并在过去几千年中多次崩溃。)
一旦我发现了问题所在,我基本上放弃了这段代码的大部分,并使用了一个我在过去用于类似任务的实现。但我真的很想确切地理解这段代码导致这个问题的原因。问题很简单,它是一个递归函数
每个函数调用都使用堆栈空间来存储其参数和局部变量,并且堆栈空间是有限的
没有理由认为此特定操作应该是递归的。事实上,当无法轻松估计或限制最大递归次数时,使用递归解决方案是个坏主意。最终它将完成所有记录,在过去几千次中多次崩溃。这是不可能的。堆栈跟踪quired。如果可以的话,我明天会再次运行它。好吧,这是有意义的。在过去,我通常只是在这样的场景中使用循环来迭代数据表中的行。因为我看到这段代码时相对较新,所以我假设最初编写它的开发人员有一些理由使用这种方法。MSDN docum我看到的entation提到了寻找无限递归,但这显然不适用于这里。