WPF ShowDialog在窗口加载期间吞咽异常

vid*_*ige 12 wpf exception

使用Window类中的ShowDialog方法显示WPF窗口对话框,就像在主窗口上按下按钮一样,如下所示.

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                var window = new Window1();
                window.ShowDialog();
            }
            catch (ApplicationException ex)
            {
                MessageBox.Show("I am not shown.");
            }
        }
Run Code Online (Sandbox Code Playgroud)

该窗口在xaml中订阅了一个Loaded事件,如下所示:

<Window x:Class="Stackoverflow.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" Loaded="Window_Loaded">
    <Grid />
</Window>
Run Code Online (Sandbox Code Playgroud)

Window_Loaded事件中抛出异常

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        throw new ApplicationException();
    }
Run Code Online (Sandbox Code Playgroud)

但是,ShowDialog调用周围没有捕获异常,调用也没有返回.吞下异常并仍然显示窗口.

为什么会发生这种情况?如何处理WPF窗口的Window_Loaded事件中的异常?我是否必须在事件处理程序中捕获它并手动处理窗口?

在WinForms中,您需要打电话 Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException)

为了让异常通过ShowDialog调用冒泡.是否需要在WPF上设置类似的开关?

mid*_*ace 7

我只在x64机器上看到过这个问题,代码用Any Cpu编译.将程序更改为编译为x84可能会修复它,但我自己也有问题,具体取决于我们的程序集.
我唯一的代码建议如下,即便如此,也不保证能够提取它.捕获异常,并将其重新抛出到Background worker中.

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    try
    {
        /// your code here...
        throw new ApplicationException();
        /// your code here...
    }
    catch (Exception ex)
    {
        if (IntPtr.Size == 8)   // 64bit machines are unable to properly throw the errors during a Page_Loaded event.
        {
            BackgroundWorker loaderExceptionWorker = new BackgroundWorker();
            loaderExceptionWorker.DoWork += ((exceptionWorkerSender, runWorkerCompletedEventArgs) => { runWorkerCompletedEventArgs.Result = runWorkerCompletedEventArgs.Argument; });
            loaderExceptionWorker.RunWorkerCompleted += ((exceptionWorkerSender, runWorkerCompletedEventArgs) => { throw (Exception)runWorkerCompletedEventArgs.Result; });
            loaderExceptionWorker.RunWorkerAsync(ex);
        }
        else
            throw;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 哦,旁注不要像这样的"抛出前"再次抛出异常 - 更好地重新抛出.喜欢这个"扔;". (4认同)