Подтвердить что ты не робот

Необязательное исключение, pt 2

Обновление: Я зарегистрировал отчет об ошибке в Microsoft Connect: https://connect.microsoft.com/VisualStudio/feedback/details/568271/debugger-halting-on-exception-thrown-inside-methodinfo-invoke#details

Если вы можете воспроизвести эту проблему на своем компьютере, пожалуйста, отсканируйте ошибку, чтобы она могла быть исправлена!


Хорошо, я провел некоторое тестирование, и я решил проблему просто:

я. Создайте метод в новом классе, который генерирует исключение:

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, который пытается игнорировать его. (Даже если вы поместите контрольную точку в блок catch, она остановится, прежде чем она ее достигнет!)

Фактически, исключение происходит, когда вы запускаете его без отладчика. В простом тестовом проекте его игнорируют на каком-то другом уровне, но если ваше приложение имеет любую глобальную обработку исключений, оно также будет запущено там. [см. Комментарии]

Это вызывает у меня настоящую головную боль, потому что он продолжает запускать мой обработчик сбоя приложения, не говоря уже о болью, которую нужно попытаться отладить.

4b9b3361

Ответ 1

Я могу воспроизвести это в своем ящике .NET 4, и вы правы - это происходит только на .NET 4.0.

Это пахнет очень как ошибка для меня, и я должен пойти на MS Connect. Основной bummer, если это отключает ваш обработчик сбоя. Звучит как непривлекательный способ обойти это, чтобы обернуть вызванный метод внутри своего обработчика.: - (

Одна вещь, которую я не могу воспроизвести, однако, отключает обработчик аварии. Здесь моя программа:

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!");
        }
    }
}

Ответ 2

Вы не можете поймать все исключения. В вашем примере есть несколько предположений. Вы, например, считаете, что исключение было поднято в вызывающем потоке. Захват необработанных исключений из других потоков зависит от того, какие среды выполнения вы используете (консоль, winforms, WPF, ASP.Net и т.д.).

Кроме того, вызовы System.Environment.FailFast() не генерируют какое-либо принудительное условие - процесс эффективно завершается без каких-либо вмешательств.