我有以下代码:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
try
{
this.CheckValue(true); // call method
}
catch(Exception ex)
{
// how to get here name of last called method
}
}
public int CheckValue(bool sender)
{
var qwe = int.Parse("qwe"); // invoke an exception
return 0;
}
}
我需要进入最后一个被调用方法的“catch block”名称(在本例中为“CheckValue”),但它返回的是被调用的方法是“StringToNumber”。
我尝试使用StackTrace获取它:
stackTrace.GetFrame(1).GetMethod().Name; -> "Main"
MethodBase.GetCurrentMethod(); -> "Void .ctor()"
ex.TargetSite.Name; -> "StringToNumber"
可以这样做吗?
答案 0 :(得分:3)
简答:
是的,你可以!!!
我只是使用扩展方法,这里的技巧是获取所需类的最后一帧,否则它将获得mscorlib程序集的方法。所以这就是:
public static string GetLastCalledMethod<T>(this Exception ex)
{
var stackTrace = new System.Diagnostics.StackTrace(ex);
var lastFrame = stackTrace.GetFrames().FirstOrDefault(frame => frame.GetMethod().DeclaringType.FullName == typeof(T).FullName);
string methodName = string.Empty;
if (lastFrame != null)
methodName = lastFrame.GetMethod().Name;
return methodName;
}
答案 1 :(得分:1)
简答:
长答案:
如果您确实需要这样做,则需要在要跟踪的所有方法中执行日志记录代码。
您可以创建一个全局变量(ugh)来存储带有最后一个被调用方法的MethodInfo
,并在每个方法中将其设置为MethodBase.GetCurrentMethod()
。然后,只要您需要,您可以检查该变量以查看它的最后设置方法。
在您的情况下,您可能正在尝试确定引发异常的方法。您正在查看TargetSite
,它返回层次结构中的最低方法,而您似乎想要紧接在现行方法。如果仅仅检查Exception.StackTrace
没有提供足够的信息,您可以解析StackTrace
中的信息并使用反射获得MethodInfo
。通常,StackTrace
足够好了。
您也可以在顶级方法中抛出新的异常,这样您就可以从新的异常中获取TargetSite
。
要点:
如果Exception.StackTrace
没有提供足够的信息,那么您将不得不:
Exception
获取哪些信息。InnerException
设置为原始异常时抛出新异常。答案 2 :(得分:0)
我不知道你为什么要这样做..因为这是预期的行为。异常的站点是你在int.Parse()调用中显示的内容。
那就是说..如果你真的想要这样做,你需要在CheckValue中包装一个try .. catch,并从那里重新抛出异常,但是以某种方式打破了调用堆栈..就像这样:
public int CheckValue(bool sender) {
try {
var qwe = int.Parse("qwe"); // invoke an exception
return 0;
}
catch (Exception ex) {
throw ex; // this breaks the call stack and re-throws the exception from here..
}
}
然后,ex.TargetSite.Name ==“CheckValue”。我仍然不确定你为什么要这样做..因为堆栈跟踪实际上会显示你在失败后从哪里解开。