views:

67

answers:

1

I'm writing a .net compact framework app in c#. It was working fine in the development environment but when built in release mode and run by itself, it was throwing MethodNotFound exceptions. I sprinkled a bunch of debug logging code to find out where it was breaking and narrowed it down to a big Init() function. This in turn calls methods on a several singleton classes which are implemented like this:

private SingletonClass() {}

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

One thing I noticed is that the debug entry from the constuctor in the singleton class would get logged before the first entry in the Init() function. It looks like the runtime engine was doing something under the hood before it actually starting running my code.

Once I had "enough" debug code in those singleton classes, it wouldn't throw the MethodNotFound exception and the program would run just fine. I say "enough" because I could comment out the debug code and get MethodNotFound. When I un-commented it again, it worked.

The weird part is that when the exception was not thrown, the debug log entries would be in the order that my code called them. It was almost like the runtime engine wasn't doing its "under the hood" stuff that it did when MethodNotFound was thrown.

I tried clearing the "Optimize code" option on the project that had the singleton classes and it seems to have solved the problem. (I tried this at first but learned the hard way that project options on the UI project don't effect the business logic project.)

The few posts about MethodNotFound that I did find talked about missing DLLs, wrong DLL versions or running low on memory.

I did find a post that talks about how the compiler deals with static stuff used in singleton classes.

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

I think it's related to the problem I'm having but in the end I had to clear "optimize code" to get it to work.

So my question is what the heck is going on? It's working so this is an academic question at this point. Hopefully this will save someone else the headache.

+2  A: 

Are you using reflection anywhere in your code to walk the call stack? (search for StackFrame or StackTrace classes)

Small functions are often inlined when code is optimised, which means particular methods may disappear entirely from the call stack in a release build. If you're expecting that method to be there in the call stack, you may be seeing inlining.

When you add debugging code to a small function, I'm guessing that the JIT stops judging it as an inlineable function, and so the method goes back into the call stack and your problem disappears.

You can mark a method as not-inlinable with the CompilerServices.MethodImpl attribute. try applying this to one of your functions which was 'fixed' by adding debug code.

See also http://blogs.msdn.com/davidnotario/archive/2004/11/01/250398.aspx

Steve Cooper
From the link above: "A typical example of a really good candidate for inlining is a property getter/setter."I added [MethodImpl(MethodImplOptions.NoInlining)] to the "get" statements of the "Instance" properties, checked "Optimize code" and it worked. Good call! Thanks for the tip.
Patrick
no problem. Glad to have helped.
Steve Cooper