当前位置: 首页 >服务端 > WPF整理-处理没有注意到的异常

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

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

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

举例来说明。

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

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

WPF整理-处理没有注意到的异常 _ JavaClub全栈架构师技术笔记

<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运行程序。
WPF整理-处理没有注意到的异常 _ JavaClub全栈架构师技术笔记

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

 

 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程序的异常捕获总结

作者:DebugLZQ
来源链接:https://www.cnblogs.com/DebugLZQ/p/3161185.html

版权声明:
1、JavaClub(https://www.javaclub.cn)以学习交流为目的,由作者投稿、网友推荐和小编整理收藏优秀的IT技术及相关内容,包括但不限于文字、图片、音频、视频、软件、程序等,其均来自互联网,本站不享有版权,版权归原作者所有。

2、本站提供的内容仅用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人及本网站的合法权利。
3、本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站(javaclubcn@163.com),我们将第一时间核实后及时予以删除。





本文链接:https://www.javaclub.cn/server/112217.html

标签:异常处理
分享给朋友:

“WPF整理-处理没有注意到的异常” 的相关文章