これは、今朝あまりうまくいかなかった質問のバージョンを提示する新しい試みです。
次のプログラムを考えてみましょう。このプログラムは、Visual Studio 2010 内で 1 回実行し、実行可能ファイルを直接ダブルクリックしてもう一度実行します。
namespace ConsoleApplication3
{
delegate void myFoo(int i, string s);
class Program
{
static void Main(string[] args)
{
Foo(1, "hello");
Delegate Food = (myFoo)Foo;
Food.DynamicInvoke(new object[] { 2, null });
}
static void Foo(int i, string s)
{
Console.WriteLine("If the next line triggers an exception, the stack will be unwound up to the .Invoke");
Console.WriteLine("i=" + i + ", s.Length = " + s.Length);
}
}
}
VS の実行中に Foo の例外がトリガーされると、デバッガーはスタックを正しく表示し、Foo の 2 番目の WriteLine で問題が発生したことを示します。
しかし、実行可能ファイルを直接実行しているときに例外が発生すると、CLR から小さなポップアップ ウィンドウが表示され、プログラムが未処理の例外をスローしたことが示されます。[デバッグ] をクリックし、VS デバッガーを選択します。この場合、スタックは最新の .DynamicInvoke の時点まで巻き戻され、デバッガーでアタッチすると、例外の時点で存在していたスタック コンテキストが部分的に失われます。
例外イベントの「内部例外」部分内に、限られた形式で存在します。クリックして関連情報を展開し、問題が発生した行番号を見つけます。しかし、明らかにローカル変数やその他のコンテキストはなくなります。
.DynamicInvoke を使用せずに同じことを試みた場合 (たとえば、Main の 1 行目で Foo(1, null) を呼び出す)、それでも .exe ファイルをダブルクリックすると、デバッガーがアタッチされたときに正しい行番号が取得されます。 . 同様に、.exe をクリックしてアプリケーションを起動すると、例外がスローされる前にデバッガーがアタッチされます。
動的リフレクション/呼び出しを使用するアプリケーションがこの問題を回避する方法を知っている人はいますか? 私の意図した使用例では、名前はここでは言及しませんが、.DynamicInvoke で使用されるオブジェクトの型シグネチャや、採用される引数の数さえも予測できません。静的型付けやジェネリックでさえ、これを回避する方法ではありません。
私の質問は次のとおりです。例外がスローされた後にプログラムにアタッチするときと、デバッガーから直接実行するときの動作が異なる理由を誰か知っていますか?