【问题标题】:MethodNotFound, singleton class and "optimize code"MethodNotFound、单例类和“优化代码”
【发布时间】:2010-01-11 22:02:26
【问题描述】:

我正在用 c# 编写一个 .net 紧凑型框架应用程序。它在开发环境中运行良好,但是当以发布模式构建并自行运行时,它会抛出 MethodNotFound 异常。我撒了一堆调试日志代码来找出它在哪里被破坏并将其缩小到一个大的 Init() 函数。这反过来又调用了几个单例类的方法,这些类的实现如下:

private SingletonClass() {}

private static readonly SingletonClass _instance = new SingletonClass();
public static SingletonClass Instance
{
 get
 {
  return _instance;
 }
}

我注意到的一件事是,来自单例类中构造函数的调试条目将在 Init() 函数中的第一个条目之前记录。看起来运行时引擎在实际开始运行我的代码之前就在幕后做了一些事情。

一旦我在这些单例类中拥有“足够”的调试代码,它就不会抛出 MethodNotFound 异常并且程序会运行得很好。我说“够了”是因为我可以注释掉调试代码并获得 MethodNotFound。当我再次取消注释时,它起作用了。

奇怪的是,当没有抛出异常时,调试日志条目将按照我的代码调用它们的顺序排列。这几乎就像运行时引擎没有像抛出 MethodNotFound 时那样做它的“幕后”工作。

我尝试在具有单例类的项目上清除“优化代码”选项,它似乎已经解决了问题。 (我一开始尝试过这个,但很难理解 UI 项目上的项目选项不会影响业务逻辑项目。)

我确实找到了几篇关于 MethodNotFound 的帖子,其中提到了缺少 DLL、错误的 DLL 版本或内存不足。

我确实找到了一篇关于编译器如何处理单例类中使用的静态内容的帖子。

http://www.yoda.arachsys.com/csharp/singleton.html

我认为这与我遇到的问题有关,但最后我必须清除“优化代码”才能使其正常工作。

所以我的问题是到底发生了什么?它正在起作用,所以目前这是一个学术问题。希望这可以避免其他人的头痛。

【问题讨论】:

    标签: .net compact-framework singleton methodnotfound


    【解决方案1】:

    您是否在代码中的任何位置使用反射来遍历调用堆栈? (搜索 StackFrame 或 StackTrace 类)

    优化代码时通常会内联小函数,这意味着特定方法可能会在发布版本中完全从调用堆栈中消失。如果您希望该方法存在于调用堆栈中,您可能会看到内联。

    当您将调试代码添加到一个小函数时,我猜测 JIT 不再将其判断为可内联函数,因此该方法返回调用堆栈,您的问题就消失了。

    您可以使用CompilerServices.MethodImpl 属性将方法标记为不可内联。尝试将此应用到您通过添加调试代码“修复”的功能之一。

    另请参阅 http://blogs.msdn.com/davidnotario/archive/2004/11/01/250398.aspx

    【讨论】:

    • 来自上面的链接:“一个非常好的内联候选者的典型示例是属性 getter/setter。”我将 [MethodImpl(MethodImplOptions.NoInlining)] 添加到“Instance”属性的“get”语句中,检查了“Optimize code”并且它起作用了。好决定!感谢您的提示。
    猜你喜欢
    • 1970-01-01
    • 2022-11-23
    • 1970-01-01
    • 2012-12-12
    • 2015-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多