情境: 我在客户端机器上运行了数百个应用程序实例,从事某项工作。像云应用程序的东西。
目标:当其中任何一个发生错误时,我想将错误报告给错误日志数据库,然后静默退出应用程序以避免用户烦恼。
问题: 我最近迁移到VB.NET并且不知道这是错误处理代码的最佳方法。这些实例在计时器下运行例程。
Private Sub timerLifeSignal_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles timerLifeSignal.Tick
MAINSUB()
End Sub
Friend Sub MAINSUB()
frmSAN.timerLifeSignal.Enabled = False
...
'do the job
...
frmSAN.timerLifeSignal.Enabled = True
end sub
乍一看我已经将 try / catch放入每个函数但是它会导致内存泄漏,因为AFIK,创建的异常对象没有正确处理。
那么有没有办法让try / catch在这些情况下不会出现内存泄漏?
THX,
更新 基本上我正在做的是:
Private Sub timerLifeSignal_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles timerLifeSignal.Tick
MAINSUB()
End Sub
Friend Sub MAINSUB()
Try
frmSAN.timerLifeSignal.Enabled = False
...
'do the job
...
frmSAN.timerLifeSignal.Enabled = True
Catch ex as Exception : gERRFUNC(" | MAIN | " & ex.Message) : End Try
end sub
friend sub dothejob
try
...
' really do the job
...
Catch ex as Exception : gERRFUNC(" | MAIN | " & ex.Message) : End Try
end sub
依此类推......最后(可能在这里是我的错误)另一个try / catch嵌套在这里:
Public Sub gERRFUNC(Optional ByVal errorMSG As String = "")
Try
' log message on database
SQL = "INSERT INTO sanerrorlog VALUES (NULL, '" & currentMySQLTime() & "', '" & errorMSG & "');"
' function that open conn and execute the sql... working fine
' NOTE THAT INSIDE THE DORS FUNCTION THERE'S ALSO A TRY/CATCH USING THE SAME EX OBJECT.
DORS(SQL)
' clean up things
SQL = "DELETE FROM sannie WHERE sid=" & gMyID
DORS(SQL)
For i = 0 To UBound(gCONN)
If gCONN(i).State = ConnectionState.Open Then gCONN(i).Close()
Next
frmSAN.nfi.Visible = False
gWWB = Nothing
End
Catch E As Exception: End: End Try
End Sub
所以...如果我这样做:
Private Sub timerLifeSignal_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles timerLifeSignal.Tick
Try
MAINSUB()
Catch ex as Exception : gERRFUNC(" | MAIN | " & ex.Message) : End Try
End Sub
是否应该捕获mainsub中的所有异常?
答案 0 :(得分:1)
你有另一种方式..
您可以将事件附加到应用程序域和主线程,以防它失败,以捕获错误。
类似的东西:
AppDomain.CurrentDomain.UnhandledException +=
CurrentDomain_UnhandledException;
Application.ThreadException +=
Application_ThreadException;
Application.ApplicationExit += Application_ApplicationExit;
考虑到这一点,每次发生异常时,任何它本身都没有捕获的地方都将落入任何一个......
答案 1 :(得分:0)
尝试/捕捉自身不会导致内存泄漏。然而,失败后不是finalizing
某事,而是触发catch
。通过删除你的try / catches,你显然已经暴露了其他确实最终确定的东西,即使是非正式的,导致内存泄漏的对象。
问问自己,代码中的指令怎么会导致内存泄漏?尝试,也不是Catch是对象的引用,因此不能自己引起内存消耗问题 - 只能通过它们控制的代码的逻辑路径。
答案 2 :(得分:0)
仅供参考,因为嵌套的try / catch循环(由于我的错误)使用相同的变量作为异常对象,因此发生内存泄漏问题。 为了更清楚,请参考以下示例:
Public Sub gERRFUNC(Optional ByVal errorMSG As String = "")
Try
// do something wrong here
Catch E As Exception: gERRFUNC(ex.Message): End Try
End Sub
friend Sub gERRFUNC(msg as string)
Try
// call another external sub (wich eventually may also throw an execption)
// take note that the var 'E' is also referenced here and everywhere
// so as 'E' is set it enters on a Exception loop causing the 'memory leak' problem.
Catch E as Exception: End: End Try
End Sub
通过删除嵌套的try / catch或使用结构良好的错误“flow”可以避免这些类型的问题。
最诚挚的问候, 保罗布埃诺。