0

我得到的异常堆栈跟踪是:

/* snip */
at SomeSystemMethod()
at Namespace.Adapters.ListAdapterBase`1.GetObjects(String where)
at Namespace.Processes.MyProcess.Run()
/* snip */

这似乎在第二行之后缺少了一些东西,因为 ListAdapterBase 是抽象的,并且方法 GetObjects 不是直接调用的,而是由子类的另一个方法调用的:

public class ActualStateList : ListAdapterBase<ActualState>
{
    /* snip */
    public List<ActualState> GetByUserId(int userId)
    {
        return GetObjects(string.Format(
            WHERECLAUSE_BYUSERID, userId));
    }
    /* snip */
}

所以我的第一个问题是,Stacktrace 中怎么可能没有调用ActualStateList.GetByUserId()或其他子类或方法?

其次:该Run()方法使用了 ListAdapterBase 的 4 个子类,我能以某种方式找出异常发生在哪个子类中吗?ListAdapterBase 后面的数字是否以某种方式精确地导致了其中一个子类?

4

2 回答 2

3

第一个问题:很可能GetByUserId在您的发布版本中内联,这就是堆栈跟踪中没有丢失它的原因。使用 Debug 构建应该显示该方法。

第二个问题:从您得到的 StackTrace 中,您无法推断出使用了哪个子类。数字 ( `1) 是类名的一部分,ListAdapterBase简单地说明这个类有一个通用参数。

但是有一个想法:由于 JIT 能够内联GetByUserId您知道某些事情:

  • JIT 在编译时知道哪个子类被用作virtual方法没有内联。
  • 只有调用的子类GetObjects才是使用的特定子类的候选者
  • 只有以简单方法GetObjects调用的子类才是候选者。

这些要点可能会帮助您找到特定的子类。

Run添加 pdb 文件可能会有所帮助,因为它会在引发异常的方法中显示行号。发布版本也可以添加 pdb 文件。

于 2012-09-19T10:51:29.507 回答
0

正如丹尼尔所说,该GetByUserId方法似乎已被编译器内联,这就是您在堆栈跟踪中看不到它的原因。

`1after意味着它是具有一个类型参数的ListAdapterBase泛型类型,这在这里当然没有帮助,因为您的所有派生类都有一个类型参数。您将无法仅从堆栈跟踪中找到它是哪一个。

于 2012-09-19T10:53:22.543 回答