vb.net 定时器和异常(try...catch)和内存泄漏
场景: 我有数百个应用程序实例在客户端计算机上运行,执行特定的工作。类似云应用程序之类的东西。
目标:当其中任何一个发生错误时,我想将错误报告给错误日志数据库并默默退出应用程序以避免用户烦恼。
问题: 我最近迁移到 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在这种情况下不发生内存泄漏呢?
谢谢,
更新: 基本上我正在做的事情是这样的:
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 中的所有异常都应该被捕获?
Scenario:
I've hundreds of applications instances running on client machines doing a certain job. Something like a cloud app.
Objective: When an error occur in any of them i want to report the error to an error-log database an quit silently the app to avoid user annoyance.
The problem:
I've migrate to VB.NET recently and don't know yet wich is the best aproach to error handle the code. Those instances are runing a routine under a timer.
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
At first glance i've put try/catch into every single function but it leads to a memory leak since, AFIK, the exception object created was not disposed correctly.
So is there a way to make try/catch do not memory leak under these circumstances?
Thx,
UPDATE:
Basically what i was doing is something like:
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
and so on... and finally (may here it's my mistake) another try/catch nested into here:
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
So... if i do this:
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
Means all exceptions inside mainsub should be catched?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您还有另一种方法..
您可以将事件附加到应用程序域和主线程,以防失败,以捕获错误。
类似的:
考虑到这一点,每次发生异常时,任何它本身没有捕获的地方都会陷入其中的任何一个......
You have another way..
You can attach events to the app domain and main thread, in case it fails, to catch the errors.
Something like:
with this in mind, every time an exception occurs, anywhere that it hasn't a catch by itself, will fall trough any of this ones...
Try/Catches 本身不会导致内存泄漏。然而,在失败后不
最终化
某些内容会触发catch
。通过删除您的 try/catch,您显然暴露了其他确实最终确定(即使是非正式的)导致内存泄漏的对象的东西。问问自己,代码中的指令如何导致内存泄漏? Try 和 Catch 都不是对对象的引用,因此它们本身不会导致内存消耗问题——仅通过它们控制的代码的逻辑路径引起。
Try/Catches by themselves don't cause memory leaks. Not
finalizing
something after a failure, which triggers acatch
can however. By removing your try/catches, you've apparently exposed something else that does finalize, even though informally, the object which was causing a memory leak.Ask yourself this, how could a directive in your code cause a memory leak? Try, nor Catch are references to an object, and thus could not cause memory consumption issue by themselves -- only by the logical path of the code they control.
仅供参考,由于嵌套的 try/catch 循环(我的错误)使用与异常对象相同的变量,所以发生了内存泄漏问题。
为了更清楚,请看以下示例:
通过删除嵌套的 try/catch 或使用结构良好的错误“流”可以避免此类问题。
此致,
保罗·布埃诺.
Just for reference the memory leak problem occurs because of nested try/catch loops wich (by my mistake) uses the same variable as exception object.
To be more clear take the following example:
By removing the nested try/catch or by using a well structured error 'flow' may avoid these type of problem.
Best Regards,
Paulo Bueno.