学习堆栈调用和异常的一个很好的例子
其实就是从SDK上看到的例子,觉得这个例子很好,就拿出来了,代码如下:
using System;
using System.Diagnostics;
namespace SFCS
{
// This console application shows various ways to use and
// manipulate StackFrames
class ConsoleApp
{
[STAThread]
static void Main(string[] args)
{
SFCS1.Class1 myClass = new SFCS1.Class1();
try {
myClass.MyMethod();
}
catch (Exception) {
// Display file and line information, if available.
StackTrace st = new StackTrace(new StackFrame(true));
Console.WriteLine(" StackTrace: " + st.ToString());
Console.WriteLine(" Line Number : " +
st.GetFrame(0).GetFileLineNumber().ToString());
Console.WriteLine("-------------------------------------------------\n");
}
}
}
}
namespace SFCS1
{
public class Class1
{
public void MyMethod()
{
try
{
SFCS2.Class1 myClass = new SFCS2.Class1();
myClass.MyMethod();
}
catch (Exception e)
{
// There are two frames on the stack, skip the
// current one. By default, file and line information
// are not displayed.
StackTrace st = new StackTrace(new StackFrame(1));
Console.WriteLine(" StackTrace: " + st.ToString());
// Is not equivalent to
Console.WriteLine(" StackFrame: " + st.GetFrame(0).ToString());
Console.WriteLine(" Line Number : " +
st.GetFrame(0).GetFileLineNumber().ToString());
Console.WriteLine("-------------------------------------------------\n");
throw e;
}
}
}
}
namespace SFCS2
{
public class Class1
{
public void MyMethod()
{
try {
SFCS3.Class1 myClass = new SFCS3.Class1();
myClass.MyMethod();
}
catch (Exception e) {
// There are currently three frames on the stack.
StackTrace st1 = new StackTrace(true);
Console.WriteLine(" The Three Frames Are: " + st1.ToString());
// You can skip frames during StackFrame construction
StackTrace st2 = new StackTrace(new StackFrame(1, true));
Console.WriteLine(" This : " + st2.ToString());
// This is similar to skipping frames during StackTrace construction
StackTrace st3 = new StackTrace(1, true);
Console.WriteLine(" Is not equivalent to : " + st3.ToString());
Console.WriteLine(" Though they both omit the SFCS2.Class1.MyMethod()" +
" method call\n");
Console.WriteLine("-------------------------------------------------\n");
throw e;
}
}
}
}
namespace SFCS3
{
public class Class1
{
public void MyMethod()
{
try {
SFCS4.Class1 myClass = new SFCS4.Class1();
myClass.MyMethod();
}
catch (Exception e) {
StackTrace st = new StackTrace(new StackFrame("source.cs", 60));
Console.WriteLine(" StackTrace: " + st.ToString());
for(int i =0; i< st.FrameCount; i++ )
{
StackFrame sf = st.GetFrame(i);
Console.WriteLine(" File: {0}", sf.GetFileName());
Console.WriteLine(" Line Number: {0}", sf.GetFileLineNumber());
// The column number defaults to zero when not initialized.
Console.WriteLine(" Column Number: {0}", sf.GetFileColumnNumber());
Console.WriteLine(" Intermediate Language Offset: {0}", sf.GetILOffset());
Console.WriteLine(" Native Offset: {0}", sf.GetNativeOffset());
}
Console.WriteLine("-------------------------------------------------\n");
throw e;
}
}
}
}
namespace SFCS4
{
public class Class1
{
public void MyMethod()
{
try {
SFCS5.Class1 myClass = new SFCS5.Class1();
myClass.MyMethod();
}
catch (Exception e) {
StackTrace st = new StackTrace(new StackFrame("source.cs", 79, 24));
Console.WriteLine("\n StackTrace: " + st.ToString());
// StackTrace.ToString only included the
// MethodBase name. You must access the
// StackFrames explicitly to get filename
// and line number information
for(int i =0; i< st.FrameCount; i++ )
{
StackFrame sf = st.GetFrame(i);
Console.WriteLine(" File: {0}", sf.GetFileName());
Console.WriteLine(" Line Number: {0}", sf.GetFileLineNumber());
Console.WriteLine(" Column Number: {0}", sf.GetFileColumnNumber());
}
Console.WriteLine("-------------------------------------------------\n");
throw e;
}
}
}
}
namespace SFCS5
{
public class Class1
{
public void MyMethod()
{
throw new Exception("StackFrame Example");
}
}
}
using System.Diagnostics;
namespace SFCS
{
// This console application shows various ways to use and
// manipulate StackFrames
class ConsoleApp
{
[STAThread]
static void Main(string[] args)
{
SFCS1.Class1 myClass = new SFCS1.Class1();
try {
myClass.MyMethod();
}
catch (Exception) {
// Display file and line information, if available.
StackTrace st = new StackTrace(new StackFrame(true));
Console.WriteLine(" StackTrace: " + st.ToString());
Console.WriteLine(" Line Number : " +
st.GetFrame(0).GetFileLineNumber().ToString());
Console.WriteLine("-------------------------------------------------\n");
}
}
}
}
namespace SFCS1
{
public class Class1
{
public void MyMethod()
{
try
{
SFCS2.Class1 myClass = new SFCS2.Class1();
myClass.MyMethod();
}
catch (Exception e)
{
// There are two frames on the stack, skip the
// current one. By default, file and line information
// are not displayed.
StackTrace st = new StackTrace(new StackFrame(1));
Console.WriteLine(" StackTrace: " + st.ToString());
// Is not equivalent to
Console.WriteLine(" StackFrame: " + st.GetFrame(0).ToString());
Console.WriteLine(" Line Number : " +
st.GetFrame(0).GetFileLineNumber().ToString());
Console.WriteLine("-------------------------------------------------\n");
throw e;
}
}
}
}
namespace SFCS2
{
public class Class1
{
public void MyMethod()
{
try {
SFCS3.Class1 myClass = new SFCS3.Class1();
myClass.MyMethod();
}
catch (Exception e) {
// There are currently three frames on the stack.
StackTrace st1 = new StackTrace(true);
Console.WriteLine(" The Three Frames Are: " + st1.ToString());
// You can skip frames during StackFrame construction
StackTrace st2 = new StackTrace(new StackFrame(1, true));
Console.WriteLine(" This : " + st2.ToString());
// This is similar to skipping frames during StackTrace construction
StackTrace st3 = new StackTrace(1, true);
Console.WriteLine(" Is not equivalent to : " + st3.ToString());
Console.WriteLine(" Though they both omit the SFCS2.Class1.MyMethod()" +
" method call\n");
Console.WriteLine("-------------------------------------------------\n");
throw e;
}
}
}
}
namespace SFCS3
{
public class Class1
{
public void MyMethod()
{
try {
SFCS4.Class1 myClass = new SFCS4.Class1();
myClass.MyMethod();
}
catch (Exception e) {
StackTrace st = new StackTrace(new StackFrame("source.cs", 60));
Console.WriteLine(" StackTrace: " + st.ToString());
for(int i =0; i< st.FrameCount; i++ )
{
StackFrame sf = st.GetFrame(i);
Console.WriteLine(" File: {0}", sf.GetFileName());
Console.WriteLine(" Line Number: {0}", sf.GetFileLineNumber());
// The column number defaults to zero when not initialized.
Console.WriteLine(" Column Number: {0}", sf.GetFileColumnNumber());
Console.WriteLine(" Intermediate Language Offset: {0}", sf.GetILOffset());
Console.WriteLine(" Native Offset: {0}", sf.GetNativeOffset());
}
Console.WriteLine("-------------------------------------------------\n");
throw e;
}
}
}
}
namespace SFCS4
{
public class Class1
{
public void MyMethod()
{
try {
SFCS5.Class1 myClass = new SFCS5.Class1();
myClass.MyMethod();
}
catch (Exception e) {
StackTrace st = new StackTrace(new StackFrame("source.cs", 79, 24));
Console.WriteLine("\n StackTrace: " + st.ToString());
// StackTrace.ToString only included the
// MethodBase name. You must access the
// StackFrames explicitly to get filename
// and line number information
for(int i =0; i< st.FrameCount; i++ )
{
StackFrame sf = st.GetFrame(i);
Console.WriteLine(" File: {0}", sf.GetFileName());
Console.WriteLine(" Line Number: {0}", sf.GetFileLineNumber());
Console.WriteLine(" Column Number: {0}", sf.GetFileColumnNumber());
}
Console.WriteLine("-------------------------------------------------\n");
throw e;
}
}
}
}
namespace SFCS5
{
public class Class1
{
public void MyMethod()
{
throw new Exception("StackFrame Example");
}
}
}
可以使用单步调试的方法一步一步地执行代码,学习StackTrace和StackFrame这两个类的使用,看看方法是如何调用的,在这个过程中也可以学习如何使用throw来抛出异常给调用方法,使得可以进一步处理该异常。