2011-10-12 33 views
0

场景: 我有数百个应用程序实例在客户机上运行,​​执行某项工作。就像一个云应用程序。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在这些情况下不会发生内存泄漏?

THX,

UPDATE: 基本上我在做什么是一样的东西:

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

'Try/catch'不是内存泄漏。显然,'做这份工作'还有其他的东西。 – GSerg

+0

我已经检查过它。通过删除所有尝试/捕获内存泄漏停止。我读过某处(丢失链接,对不起),异常是一个对象本身,意味着它必须妥善处置。由于这些函数下降到4级,可能vb垃圾收集器不会清除这些objetcs。 –

+0

@Paulo异常没有Dispose方法,因此不能处理。你显然看到的是还没有被垃圾回收的异常对象(但最终会)。 – GSerg

回答

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或通过使用结构良好错误“流”可避免这些类型的问题。

最好的问候, Paulo Bueno。

0

尝试/捕捉自己不会导致内存泄漏。不是finalizing失败后的事情,但触发catch可以。通过删除你的try/catch,你显然已经暴露了一些别的东西,即使非正式地确定了导致内存泄漏的对象。

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

+0

那么,它对我来说不是很清楚。因为如果发生故障,它必须被try/catch中的一个捕获,并且在这些情况下,我(在catch例程中)清理事件,报告和退出应用程序。也没有得到暴露的部分... –

1

你有另一种方式..

您可以将事件附加到应用程序域和主线程,万一失败,赶上错误。

喜欢的东西:

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

考虑到这一点,每一个异常发生时,任何地方,它没有一个catch本身将下降低谷任何这种的人的...