MethodNotFound,单例类和“优化代码”

时间:2010-01-08 23:21:21

标签: .net compact-framework singleton methodnotfound

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

private SingletonClass() {}

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

我注意到的一件事是,在Init()函数中的第一个条目之前,将记录singleton类中的constuctor的调试条目。在实际开始运行我的代码之前,看起来运行时引擎正在做一些事情。

一旦我在那些单例类中拥有“足够”的调试代码,它就不会抛出MethodNotFound异常并且程序运行得很好。我说“够了”,因为我可以注释掉调试代码并获取MethodNotFound。当我再次对其进行评论时,它确实有效。

奇怪的是,当异常 not 抛出时,调试日志条目将按照我的代码调用它们的顺序。这几乎就像运行时引擎没有做它在引发MethodNotFound时所做的“引擎盖下”的东西。

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

我发现的关于MethodNotFound的几篇帖子谈到了丢失的DLL,错误的DLL版本或内存不足。

我找到了一篇文章,讨论编译器如何处理单例类中使用的静态内容。

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

我认为这与我遇到的问题有关,但最后我必须清除“优化代码”才能让它发挥作用。

所以我的问题是到底发生了什么?它正在发挥作用,所以这是一个学术问题。希望这会让别人头疼。

1 个答案:

答案 0 :(得分:2)

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

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

当你将调试代码添加到一个小函数时,我猜测JIT会停止将它判断为一个内联函数,因此该方法会回到调用堆栈中,你的问题就会消失。

您可以使用CompilerServices.MethodImpl属性将方法标记为不可嵌入。尝试将此应用于您通过添加调试代码“修复”的一个函数。

另见http://blogs.msdn.com/davidnotario/archive/2004/11/01/250398.aspx