only for RuBoard |
Whenever a method call is made, the Common Language Runtime creates information about that call. This information includes the location of the call within your program, the arguments that have been passed, and the local variables of the target method. The information is saved in a block of data called a stack frame . These stack frames are allocated in a region of memory called the call stack . The call stack contains all the methods that were called but have not returned to their callers . You saw this output to the console in Example 6-4.
This information can be very helpful when you track down bugs in your code. Even more helpful is the fact that you can inspect the call stack programmatically whenever you want. Example 6-5 demonstrates the process of iterating the call stack to obtain the method names that are currently active.
Imports System Imports System.Diagnostics Imports System.Reflection Public Class StackTest Public Sub MethodA( ) MethodB( ) End Sub Public Sub MethodB( ) MethodC( ) End Sub Public Sub MethodC( ) Dim i As Integer = 0 Dim st As New StackTrace( ) For i = 0 To st.FrameCount - 1 Dim sf As StackFrame = st.GetFrame(i) Console.WriteLine(sf.GetMethod.Name) Next i End Sub End Class Public Class Application Public Shared Sub Main( ) Dim test As New StackTest( ) test.MethodA( ) Console.ReadLine( ) End Sub End Class
The output from this program looks like this:
MethodC MethodB MethodA Main
This is not quite useful, but it's getting there. The System.Diagnostics.StackTrace class used in Example 6-5 is really just a collection of StackFrame objects. Alone, it doesn't do much. The StackFrame object is where your interest should lie. With it, you can obtain the filename (the GetFileName method) and line number (the GetFileLineNumber method) of the method call, as well as explicit information about the method itself, including its namespace, class, name, and the data types of the parameters passed to it. Information about the method is available from the GetMethod method, which returns an instance of the MethodBase class. This class can be used to obtain information about a method, such as whether it is public or private, its return type, or its parameters. Chapter 7 discusses this class in more detail.
As shown in Example 6-6, it is also possible to create an instance of StrackTrace that takes an exception constructor argument. This is useful for viewing the call stack at the time an exception was thrown. In this example, several methods are called in succession, and then an exception is thrown deliberately. In the Catch block of the exception handler, the caught exception is passed to a new instance of ExceptionInfo , an application-defined class designed to provide information about an exception along with the call stack.
|
Imports System Imports System.Diagnostics Imports System.Reflection Public Class StackTest Public Sub Start( ) Try MethodA( ) Catch e As Exception Dim exInfo As New ExceptionInfo(e) Console.WriteLine(exInfo.ToString( )) End Try End Sub Public Sub MethodA( ) MethodB( ) End Sub Public Sub MethodB( ) MethodC( ) End Sub Public Sub MethodC( ) Throw New ArgumentException("Simulated Error") End Sub End Class 'Reusable class for getting exception information Public Class ExceptionInfo Private exInfo As String Public Sub New(ByVal e As Exception) 'Get exception message exInfo = e.Message & Environment.NewLine Dim i As Integer = 0 Dim trace As New StackTrace(e, True) For i = 0 To trace.FrameCount( ) - 1 Dim frame As StackFrame = trace.GetFrame(i) 'Add line number, column number and file information Dim sFileInfo As String = _ String.Format("Line {0}: Col {1}: File: {2}{3}", _ frame.GetFileLineNumber( ), _ frame.GetFileColumnNumber( ), _ frame.GetFileName( ), _ Environment.NewLine) exInfo &= sFileInfo 'Add method information Dim mi As MethodBase = frame.GetMethod( ) Dim sMethodInfo As String exInfo &= mi.DeclaringType.Namespace & "." & _ mi.DeclaringType.Name & "." & mi.Name & _ Environment.NewLine exInfo &= Environment.NewLine Next i End Sub Public Overrides Function ToString( ) As String Return exInfo End Function End Class Public Class Application Public Shared Sub Main( ) Dim test As New StackTest( ) test.Start( ) Console.ReadLine( ) End Sub End Class
MethodInfo is one of several classes that are part of a .NET technology called reflection . Using reflection, you can obtain runtime information about anything you might want to know about a given object, including its methods, properties, parameters, events, enumerations, and member variableseven the stuff that's declared private. If you are curious about it, play around with the ExceptionInfo class and examine MethodInfo . Chapter 7, which deals with reflection, should give you a good understanding of this powerful tool.
only for RuBoard |