如何在程序运行时得到当前的call stack
需要引入以下的namespace
using System.Diagnostics; //For StackTrace
using System.Reflection; //MethodInfo
Step1. Create a StackTrace
StackTrace stackTrace = new StackTrace();
大多时情况下,我们希望在exception 发生时找到引发exceptioin的代码,
此时需要使用
try
{
…
}
catch(Exception exp)
{
StackTrace stackTrace = new StackTrace(exp);
}
此时通过stackTrace.ToString() 已经可以得到大致的callstack信息.
step2. 通过StatckFrame得到代码信息
int frameCount = stackTrace.FrameCount;
for (int i = 0; i < frameCount; i++)
{
StackFrame stackFrame = stackTrace.GetFrame(i);
// Display the stack frame properties.
Console.WriteLine(" File: {0}", stackFrame.GetFileName());
Console.WriteLine(" Line Number: {0}", stackFrame.GetFileLineNumber());
Console.WriteLine(" Column Number: {0}", sf.GetFileColumnNumber());
//还有很多其他的功能GetILOffset(),GetNativeOffset()…
}
step3. 通过MethodInfo得到每一个函数的信息,用到的主要是Reflection的技巧
int frameCount = stackTrace.FrameCount;
for (int i = 0; i < frameCount; i++)
{
StackFrame stackFrame = stackTrace.GetFrame(i);
MethodInfo methodInfo = (MethodInfo)stackFrame.GetMethod();
//1 get Access
string access = string.Empty;
if (methodInfo.IsPrivate)
access = "private ";
else if (methodInfo.IsPublic)
access = "public ";
else if (methodInfo.IsFamily)
access = "protected ";
else if (methodInfo.IsAssembly)
access = "Internal ";
if (methodInfo.IsStatic)
access += "static ";
//2 method nanme
string methodName = methodInfo.Name;
//3 parameter info
ParameterInfo[] pInfos = methodInfo.GetParameters();
string paramterList = string.Empty;
for (int j = 0; j < pInfos.Length; j++)
{
paramterList += string.Format(", {0} {1}", pInfos[j].ParameterType.Name, pInfos[j].Name);
}
// Get rid of the first ", " if it exists.
if (paramterList.Length > 2)
paramterList = paramterList.Substring(2);
string output = access + methodInfo.ReturnType.Name + " "+ methodName + "(" + paramterList + ")";
Console.WriteLine(output);
}
