vb.net 定时器和异常(try...catch)和内存泄漏

发布于 2024-12-09 05:53:31 字数 2466 浏览 0 评论 0原文

场景: 我有数百个应用程序实例在客户端计算机上运行,​​执行特定的工作。类似云应用程序之类的东西。

目标:当其中任何一个发生错误时,我想将错误报告给错误日志数据库并默默退出应用程序以避免用户烦恼。

问题: 我最近迁移到 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

久伴你 2024-12-16 05:53:31

您还有另一种方法..

您可以将事件附加到应用程序域和主线程,以防失败,以捕获错误。

类似的:

    AppDomain.CurrentDomain.UnhandledException +=
     CurrentDomain_UnhandledException;
    Application.ThreadException +=
      Application_ThreadException;
    Application.ApplicationExit += Application_ApplicationExit;

考虑到这一点,每次发生异常时,任何它本身没有捕获的地方都会陷入其中的任何一个......

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...

和我恋爱吧 2024-12-16 05:53:31

Try/Catches 本身不会导致内存泄漏。然而,在失败后不最终化某些内容会触发catch。通过删除您的 try/catch,您显然暴露了其他确实最终确定(即使是非正式的)导致内存泄漏的对象的东西。

问问自己,代码中的指令如何导致内存泄漏? Try 和 Catch 都不是对对象的引用,因此它们本身不会导致内存消耗问题——仅通过它们控制的代码的逻辑路径引起。

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.

平定天下 2024-12-16 05:53:31

仅供参考,由于嵌套的 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 或使用结构良好的错误“流”可以避免此类问题。

此致,
保罗·布埃诺.

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文