2

C# で .net コンパクト フレームワーク アプリを作成しています。開発環境では正常に動作していましたが、リリース モードでビルドして単独で実行すると、MethodNotFound 例外がスローされていました。デバッグ ロギング コードの束をまき散らして、壊れている場所を見つけ、それを大きな Init() 関数に絞り込みました。これは、次のように実装されているいくつかのシングルトン クラスのメソッドを呼び出します。

private SingletonClass() {}

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

私が気づいたことの 1 つは、シングルトン クラスのコンストラクターからのデバッグ エントリが、Init() 関数の最初のエントリの前にログに記録されることです。実際にコードの実行を開始する前に、ランタイム エンジンが内部で何かを行っていたようです。

これらのシングルトン クラスに「十分な」デバッグ コードがあれば、MethodNotFound 例外はスローされず、プログラムは問題なく実行されます。「十分」と言ったのは、デバッグ コードをコメント アウトして MethodNotFound を取得できるからです。もう一度コメントを外すと、うまくいきました。

奇妙な点は、例外がスローされなかった場合、デバッグ ログ エントリがコードで呼び出された順序になることです。ランタイム エンジンは、MethodNotFound がスローされたときに実行した「内部」処理を実行していないようでした。

シングルトンクラスを持つプロジェクトで「コードの最適化」オプションをクリアしてみましたが、問題は解決したようです。(最初はこれを試しましたが、UI プロジェクトのプロジェクト オプションがビジネス ロジック プロジェクトに影響しないという難しい方法を学びました。)

私が見つけた MethodNotFound に関するいくつかの投稿では、DLL が見つからない、DLL のバージョンが間違っている、またはメモリが不足しているという話がありました。

シングルトンクラスで使用される静的なものをコンパイラがどのように処理するかについて説明している投稿を見つけました。

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

私が抱えている問題に関連していると思いますが、最終的には「コードの最適化」をクリアして機能させる必要がありました。

だから私の質問は一体何が起こっているのですか?これは機能しているため、現時点では学術的な問題です。うまくいけば、これが他の誰かの頭痛を救うでしょう。

4

1 に答える 1

2

コードのどこかでリフレクションを使用してコール スタックをたどっていますか? (StackFrame または StackTrace クラスを検索します)

コードが最適化されると、小さな関数がインライン化されることがよくあります。これは、特定のメソッドがリリース ビルドのコール スタックから完全に消える可能性があることを意味します。そのメソッドがコール スタックに存在することを期待している場合は、インライン化されている可能性があります。

小さな関数にデバッグ コードを追加すると、JIT がそれをインライン化可能な関数と判断しなくなり、メソッドがコール スタックに戻り、問題が解消されると思います。

CompilerServices.MethodImpl属性を使用して、メソッドをインライン化不可としてマークできます。デバッグコードを追加して「修正」された関数の1つにこれを適用してみてください。

http://blogs.msdn.com/davidnotario/archive/2004/11/01/250398.aspx も参照してください。

于 2010-01-11T14:02:26.420 に答える