WPF Поврежденные состояния исключений.Как реализовать HandleProcessCorruptedStateExceptions - PullRequest
4 голосов
/ 18 марта 2011

Я пытаюсь поймать исключения из исправленного состояния (CES) в моем приложении WPF.Я просто хочу записать ошибку перед выходом.Мое приложение использует устаревшие библиотеки Win32 / COM, поэтому их нужно ловить.Мой код, чтобы поймать их ниже.(Я добавил HandleProcessCorruptedStateExceptions в нескольких местах, потому что он не работает в самом обработчике).Фрагмент, который генерирует сбой, находится ниже обработчика.Тем не менее, я все еще вижу диалоговое окно «Системные ошибки», и мои хендеры никогда не запускаются ... Любая помощь приветствуется

public partial class App : Application
{
    [HandleProcessCorruptedStateExceptions]
    [SecurityCritical]
    protected override void OnStartup(StartupEventArgs e) 
    { 
        base.OnStartup(e);
        AppDomain.CurrentDomain.FirstChanceException += new EventHandler<FirstChanceExceptionEventArgs>(CurrentDomain_FirstChanceException);
        AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
        DispatcherUnhandledException += new System.Windows.Threading.DispatcherUnhandledExceptionEventHandler(App_DispatcherUnhandledException);
    }

    [HandleProcessCorruptedStateExceptions]
    [SecurityCritical]
    void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
    {
        EatIt();
    }

    [HandleProcessCorruptedStateExceptions]
    [SecurityCritical]
    void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        EatIt();
    }

    [HandleProcessCorruptedStateExceptions]
    [SecurityCritical]
    void CurrentDomain_FirstChanceException(object sender, FirstChanceExceptionEventArgs e)
    {
        EatIt();
    }
    private void EatIt()
    {
        // Add some kind of logging then terminate...
    }
}

Фрагмент, который вызывает сбой

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, RoutedEventArgs e)
    {
        CrashIt();
    }
    unsafe static void CrashIt()
    {
        var obj = new byte[1];
        var pin = GCHandle.Alloc(obj, GCHandleType.Pinned);
        byte* p = (byte*)pin.AddrOfPinnedObject();
        for (int ix = 0; ix < 256; ++ix) *p-- = 0;
        GC.Collect();

    }
}

Я изменил запусккод для приложения с предложением try / catch.Все еще безуспешно.Кто-нибудь на самом деле знает, как заставить этот материал работать ???(Я все еще получаю диалоговое окно с ошибкой Windows)

public class EntryPoint
{
    // All WPF applications should execute on a single-threaded apartment (STA) thread
    [STAThread]
    [HandleProcessCorruptedStateExceptions]
    [SecurityCritical]
    public static void Main()
    {
        CustomApplication app = new CustomApplication();
        try
        {
            AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
            app.Run();
        }
        catch (Exception)
        {
            System.Diagnostics.Debug.WriteLine("xx");
        }
    }

    [HandleProcessCorruptedStateExceptions]
    [SecurityCritical]
    static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        System.Diagnostics.Debug.WriteLine("xx");
    }
}
public class CustomApplication : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);

        MainWindow window = new MainWindow();
        window.Show();
    }
}

1 Ответ

2 голосов
/ 18 марта 2011

Чтение раздела о исключениях из-за поврежденного состояния мне кажется, что для метода, который фактически выполняет try..catch, необходим атрибут, который нужно применить.Вы регистрируете обработчики для некоторых событий, поэтому ваши атрибуты не имеют никакого эффекта.

Чтение еще нескольких, кажется, что поведение изменилось между .NET 3.5 и 4.0, поэтому вы можете попробовать что-то, как написано в этой статье

Что может сработать, так это написание точки входа самостоятельно и запуск приложения WPF с помощью Initialize / Run, затем отметьте метод точки входа и напишите попытку / перехват в цикле.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...