开发者

vb.net timer and exception (try... catch) and memory leak

开发者 https://www.devze.com 2023-04-12 08:32 出处:网络
Scenario: I\'ve hundreds of applications instances running on client machines doing a certain job. Something like a cloud app.

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号