22

更新: Microsoft Connect でバグ レポートを提出しました: https://connect.microsoft.com/VisualStudio/feedback/details/568271/debugger-halting-on-exception-thrown-inside-methodinfo-invoke#details

お使いのマシンでこの問題を再現できる場合は、修正できるようにバグに賛成票を投じてください!


OK、いくつかのテストを行い、問題を非常に単純なものに減らしました。

私。例外をスローする新しいクラスにメソッドを作成します。

public class Class1 {
    public void CallMe() {
        string blah = null;
        blah.ToLower();
    }
}

ii. このメソッドを別の場所で指す MethodInfo を作成します。

Type class1 = typeof( Class1 );
Class1 obj = new Class1();
MethodInfo method = class1.GetMethod( "CallMe" );

iii. Invoke() の呼び出しを try/catch ブロックでラップします。

try {
    method.Invoke( obj, null ); // exception is not being caught!
} catch {
}

iv。デバッガーなしでプログラムを実行します (正常に動作します)。

v. デバッガーでプログラムを実行します。デバッガーは、例外を無視しようとするキャッチ ハンドラーでラップされている場合でも、例外が発生するとプログラムを停止します。(catch ブロックにブレークポイントを置いても、到達する前に停止します!)

実際、デバッガーなしで実行すると例外が発生します。単純なテスト プロジェクトでは、他のレベルでは無視されますが、アプリに何らかの種類のグローバルな例外処理がある場合は、そこでもトリガーされます。 [コメントを見る]

これは、デバッグしようとする苦痛は言うまでもなく、アプリのクラッシュハンドラーをトリガーし続けるため、本当に頭痛の種です。

4

2 に答える 2

5

.NET 4 ボックスでこれを再現できます。その通りです。これは .NET 4.0 でのみ発生します。

これは私にはバグのようなにおいがするので、MS Connect に接続する必要があります。 これがクラッシュハンドラーをトリップしている場合は、非常に残念です。これを回避するには、呼び出されたメソッドを独自のハンドラー内にラップするのが好ましくないように思えます。:-(

ただし、再現できないことの 1 つは、クラッシュ ハンドラーのトリップです。これが私のプログラムです:

namespace trash {
    public class Class1 {
        public void CallMe() {
            string blah = null;
            blah.ToLower();
        }
    }

    class Program {
        static void Main(string[] args) {
            AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);           
            var class1 = typeof(Class1);
            var method = class1.GetMethod("CallMe");

            try {
                var obj = new Class1();
                method.Invoke(obj, null); // exception is not being caught!
            }
            catch (System.Reflection.TargetInvocationException) {
                Console.Write("what you would expect");
            }

        }

        static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) {
            Console.Write("it would be horrible if this got tripped but it doesn't!");
        }
    }
}
于 2010-06-16T23:35:52.360 に答える
-1

すべての例外をキャッチすることはできません。あなたの例にはいくつかの仮定があります。たとえば、呼び出しスレッドで例外が発生したと想定しています。他のスレッドで未処理の例外をキャッチする方法は、使用しているランタイム (コンソール、winforms、WPF、ASP.Net など) によって異なります。

さらに、System.Environment.FailFast() の呼び出しは、処理可能な状態を生成しません。プロセスは介入の機会なしで効果的に終了します。

于 2010-06-16T23:34:52.613 に答える