Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 556|回复: 0

WPF整理-处理没有注意到的异常

[复制链接]
  • TA的每日心情
    奋斗
    2024-4-6 11:05
  • 签到天数: 748 天

    [LV.9]以坛为家II

    2034

    主题

    2092

    帖子

    70万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    705612
    发表于 2021-4-19 11:19:15 | 显示全部楼层 |阅读模式

    在.NET中,我们使用try-catch-finally来处理异常。但,当一个Exception抛出,抛出Exception的代码又没有被try包围时,程序就崩溃了。

    这些异常往往是你没有注意到的。在WPF中,提供了一种处理这些个异常的方式。

    举例来说明。

    1.先抛出个异常,不用try包围它。

    在MainWindow上添加一个如下的Button。

    <Window x:Class="HandlingAnUnhandledException.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525">
        <StackPanel>
            <Button Click="OnClick">
                <Button.Template>
                    <ControlTemplate>
                        <Grid>
                            <Ellipse Height="100" Width="250" Fill="Pink"/>
                            <TextBlock Text="Button to Throw Exception by DebugLZQ" VerticalAlignment="Center" HorizontalAlignment="Center"/>
                        </Grid>
                    </ControlTemplate>
                </Button.Template>
            </Button>
        </StackPanel>
    </Window>

    在Button的Click事件中抛出个异常

            private void OnClick(object sender, RoutedEventArgs e)
            {
                throw new InvalidOperationException("Something has gone wrong.");
            }

    如果,我们Ctrl+F5运行这个程序,点击按钮,程序就崩溃了。
    WPF如何解决这个问题呢?

    2.WPF处理这种异常的方法

    在App.xaml.cs中订阅DispatcherUnhandledException事件,并添加相应的事件处理。

    App.xaml.cs如下:

        public partial class App : Application
        {
            public App()
            {
                DispatcherUnhandledException += App_DispatcherUnhandledException;         }
    
            void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
            {            
                MessageBox.Show("Error encountered! Please contact support."+ Environment.NewLine + e.Exception.Message);
                //Shutdown(1);
                e.Handled = true;
            }
        }

    这时,当我们Ctrl+F5运行程序。

     这样,异常就被捕获并处理了,程序没有崩溃。 

     

     Update:刚百度了一下:WinForm也有类似的机制,请参考Kevin Gao的这篇博文:C# winform 捕获全局异常.

     Update

      所有 WPF 应用程序启动时都会加载两个重要的线程:一个用于呈现用户界面,另一个用于管理用户界面。呈现线程是一个在后台运行的隐藏线程,因此我们通常面对的唯一线程就是 UI 线程。

      这种方法只能捕捉UI线程的异常,及使用了Dispatcher进行线程关联了的线程(其实Dispatcher.Invoke/BeginInvoke就是将要执行的代码,扔到UI线程去执行)的异常。不能捕捉普通的子线程异常。

    如: 

    private void OnClick(object sender, RoutedEventArgs e)
    {
       Dispatcher.BeginInvoke(new Action(() => { throw new InvalidOperationException("Something has gone wrong."); }));
    }

    也可以正常捕获。

    而:

    private void OnClick(object sender, RoutedEventArgs e)
    {
       Thread t = new Thread(() => { throw new InvalidOperationException("Something has gone wrong."); });
       t.IsBackground = true;
       t.Start();
    }

    则不能捕获。 

    感谢veboys博友的指点~

    ------------------------------------------

    同样的,即使我们用一个try-catch包围如下的异常,异常也不会被Handle:

    try
    {
        var thread = new Thread(() => {throw new Exception(); });
        thread.Start();
    }
    catch (Exception)
    {
        MessageBox.Show("Will not execute!");
        throw;
    }

     

    try
    {
        Task.Run(() =>{throw new Exception(); });
    }
    catch (Exception)
    {
        MessageBox.Show("Will not execute!");
    }

     

    --------------

    对应Async await 异常:

    private async void ButtonBase_OnClick(object sender, RoutedEventArgs e)
            {
                try
                {
                    await Task.Run(() => { throw new Exception(); });
                }
                catch (Exception)
                {
                    MessageBox.Show("Will execute!");
                }
            }

    处理Unhandled exception异常 如下:TaskScheduler.UnobservedTaskException

        public partial class App : Application
        {
            protected override void OnStartup(StartupEventArgs e)
            {
                RegisterEvents();
                base.OnStartup(e);
            }
    
            private void RegisterEvents()
            {
                TaskScheduler.UnobservedTaskException += (sender, args) =>
                {
                    MessageBox.Show(args.Exception.Message);
                    args.SetObserved();
                };
    
                AppDomain.CurrentDomain.UnhandledException += (sender, args) => MessageBox.Show("Unhandled exception.");
            }
        }

     

     Update

    WPF程序的异常捕获总结

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-5-18 18:51 , Processed in 0.062635 second(s), 28 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表