您的位置:首页 > 编程语言 > C#

WPF异常捕获,并使程序不崩溃!

2017-09-29 14:02 471 查看
在.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>


在Bu
f455
tton的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 应用程序启动时都会加载两个重要的线程:一个用于呈现用户界面,另一个用于管理用户界面。呈现线程是一个在后台运行的隐藏线程,因此我们通常面对的唯一线程就是 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.");
}
}


 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c# WPF bug 异常捕获