vb.net timer and exception (try... catch) and memory leak
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?
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:
AppDomain.CurrentDomain.UnhandledException +=
CurrentDomain_UnhandledException;
Application.ThreadException +=
Application_ThreadException;
Application.ApplicationExit += Application_ApplicationExit;
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 by themselves don't cause memory leaks. Not finalizing
something after a failure, which triggers a catch
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.
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:
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
By removing the nested try/catch or by using a well structured error 'flow' may avoid these type of problem.
Best Regards, Paulo Bueno.
精彩评论