2

是否可以在 PostError 中确定调用方法名称“Eat Pizza”?我想我可以将“EatPizza”作为参数之一传递,但是每次方法名称更改时都需要更改(不必要的维护)。但是,我什至无法在“EatPizza”的上下文中找到方法名称“EatPizza”(使用 stacktrace、getframe、getmethod)。

public void EatPizza(Pizza p){
    if(p==null){ //A arbitrary made up error
        Utilities.PostError();
    }
    else{
        p.Slices -= 1;
    }
}

...

public void PostError(){
    //Basically posting to database the name of the method
    //Tried this, didn't work: (new StackTrace(true)).GetFrame(5).GetMethod().Name
    //Is it possible to determine the calling method name "Eat Pizza" in this context?
}

当我在 StackTrace.GetFrame 中尝试不同的值(0 到 StackTrace.FrameCount-1)时,我得到以下值,而我只想要“EatPizza”:

.ctor
ThreadStart
Main
_nExecuteAssembly
RunUsersAssemblyDebugInZone
4

2 回答 2

4

您在创建StackTrace对象方面走在了正确的轨道上,但您似乎误解了GetFrame. 帧从最底部的帧开始编号,因此:

  • GetFrame(0)会回来PostError
  • GetFrame(1)将返回调用者PostError

所以试试这个:

var trace = new StackTrace(true);
WriteToDB(trace.GetFrame(1).GetMethod().Name);

就个人而言,我更愿意获取整个堆栈跟踪,而不仅仅是调用者,所以我会这样做:

var trace = new StackTrace(true);
WriteToDB(trace.ToString());
于 2011-04-14T17:53:55.480 回答
2

是否可以在 PostError 中确定调用方法名称“Eat Pizza”?我想我可以将“EatPizza”作为参数之一传递,但是每次方法名称更改时都需要更改(不必要的维护)。

在所有可能出错的方法中调用 PostError 也是“不必要的维护”。它还使程序的执行流程复杂化,因为您必须在各处检查错误,而高级进程必须检查低级进程是否成功完成。

最好使用 CLR 和 C# 提供的异常处理结构。

发生错误的确切位置存储在异常的 StackTrace 属性中。

pubic void BigDinnerEatingProcess()
{
    try
    {
         WhateverHappensAtTheTopLevel();
    }
    catch (PizzaNotDeliveredException ex)
    {
         Utilities.PostError(ex);
         MessageBox.Show("Dinner was not eaten. Please make sure the pizza is delivered.");
    }
}

public void EatPizza(Pizza p)
{
    if (p == null)
        throw new PizzaNotDeliveredException();
    p.RemoveOneSlice();
}

private void PostError(Exception ex)
{
    string errorLocation = ex.StackTrace;
    //...
}
于 2011-04-14T18:05:09.230 回答