The ultimate question is about the speed hit on this. When the CallStack is active it brings the app to its knees as it writes every call to file which is ungodly slow. I only use it to track down a bug that I can't find and otherwise it's off until needed again.
I've implemented a CallStack engine in my programming which makes it a lot simpler to find errors that bring down an application. The application I'm working on has Events triggering all over the place. It's a huge program (for me) at about 130K lines of code right now and maybe 30% complete.
This is in every procedure that won't call itself recursively. Obviously CallStack.Add shouldn't have a CallStack.Add call in it.
Then at the end I need to pop the call off the stack. Simple, right?
But that means having a Label to go to instead of just an Exit.
E.g. If FileName = vbNullString Then Exit Function
becomes
If FileName = vbNullString Then GoTo CleanUp
....
CleanUp:
CallStack.DeleteProcedureCall
===========================
Now if I forget to delete the call or something unexpected happens kicks out of a procedure before hitting that then I have orphaned stuff on the stack.
So what I did was create a CallStacker Class that self-deletes when it goes out of scope.
Thus This:
Becomes This:Code:Public Property Get Field(ByVal Index As VENDOR_FIELD) As Variant On Error GoTo errHandler If DebugMode = idx_Debug_On Then CallStack.Add NAME & ".Field(Public Property Get)" If IsNull(vField(Index)) Then GoTo CleanUp Field = Fielder.OutFielder(Index, vField(Index)) CleanUp: If DebugMode = idx_Debug_On Then CallStack.DeleteProcedureCall Exit Property errHandler: Dim nErrorHandlerResult As Long nErrorHandlerResult = ErrorHandler(Error, Err, "Index = " & CStr(Index), NAME & ".Field(Public Property Get)") Resume CleanUp End Property
cCallStacker Class:Code:Public Property Get Field(ByVal Index As VENDOR_FIELD) As Variant Dim m_CallStacker As New cCallStacker On Error GoTo errHandler m_CallStacker.Add NAME & ".Field(Public Property Get)" If IsNull(vField(Index)) Then Exit Property Field = Fielder.OutFielder(Index, vField(Index)) Exit Property errHandler: Dim nErrorHandlerResult As Long nErrorHandlerResult = ErrorHandler(Error, Err, "Index = " & CStr(Index), NAME & ".Field(Public Property Get)") End Property
Code:Option Explicit ' Eliminates need for each Procedure to call DeleteProcedureCall. ' DeleteProcedureCall is called automatically when instance of this class goes out of scope. ' // Constants, Types and Enums. Private Const NAME As String = "cCallStacker" ' / Constants, Types and Enums. Public Sub Add(ByRef ProcedureInfo As String) If DebugMode = idx_Debug_Off Then Exit Sub CallStack.Add ProcedureInfo End Sub Private Sub Class_Terminate() If DebugMode = idx_Debug_Off Then Exit Sub CallStack.DeleteProcedureCall End Sub



Reply With Quote