250人参与 • 2024-08-02 • Windows Phone
正常情况下,开发过程中都会使用try…catch
在可能会出现异常的地方去捕获和处理异常。然而实际上开发过程中,由于开发疏忽和一些未知原因,程序中会存在未被处理的异常,当程序运行到此,可能会导致程序崩溃的情况,这样会大大的降低用户的使用体验。对于这种未发现未处理的异常,称之为未捕获异常(unhandledexception)。
下面的案例中,就是模拟一个未捕获的异常场景,点击按钮,抛出异常,不使用try…catch 捕获处理。
private void button_click(object sender, routedeventargs e)
{
throw new exception("一个异常!");
}
这种由于未捕获异常导致的程序崩溃,从而影响使用者的正常操作,交互上很不友好。此类异常如果需要追溯就必须去查看windows的事件日志,导致查找问题也比较麻烦。
我们虽然不能完全杜绝未捕获异常的产生,但是当其出现的时候,我们应当予以处理,做到尽量不影响使用者的操作。
在wpf应用程序中,各类未处理异常及其处理方式如下:
异常种类 | 处理方式 | 案例说明 |
---|---|---|
ui线程抛的异常 | 使用application.current.dispatcherunhandledexception 事件处理 | 例如点击了用户界面上面的某个控件,然后执行某行代码的时候,遇到了异常; |
非ui线程抛的异常 | 使用appdomain.currentdomain.unhandledexception事件处理 | 例如在一个多线程的程序里面,工作线程的代码遇到了异常。 |
task线程抛的异常 | 使用taskscheduler.unobservedtaskexception事件处理 | 例如在一个多线程的程序里面,工作线程的代码遇到了异常。 |
具体验证代码如下:
上面测试结果:
如何配置legacyunhandledexceptionpolicy 呢?只需要在 app.config 文件的 <runtime>
节点中添加如下代码:
<legacyunhandledexceptionpolicy enabled="1"/>
具体使用案例如下所示:
上面测试结果:
上面测试结果:
通过上面的案例中,我们发现在task中发生异常了以后,并不会马上执行unobservedtaskexception 事件内的代码,而是会等一会儿才执行? 这是因为task异常只有在垃圾回收的时候,才会推送到该事件内进行处理。
如果我们在项目将三类异常的捕获事件,全部定义出来,即可捕获所有的异常事件。
<stackpanel>
<button content="测试ui线程异常" width="300" height="50" click="button_click" margin="10"></button>
<button content="测试thread线程异常" width="300" height="50" click="button_click_1" margin="10"></button>
<button content="测试task线程异常" width="300" height="50" click="button_click_2" margin="10"></button>
</stackpanel>
private void button_click(object sender, routedeventargs e)
{
throw new exception("ui线程异常[01]!");
}
private void button_click_1(object sender, routedeventargs e)
{
new thread(new threadstart(()=>
{
throw new exception("thread多线程异常[02]");
})).start();
}
private void button_click_2(object sender, routedeventargs e)
{
task.run(()=>
{
throw new exception("task多线程异常[03]");
});
}
public partial class app : application
{
public app()
{
//当应用程序引发但未处理异常时出现,ui线程的异常,无法捕获多线程异常
application.current.dispatcherunhandledexception += current_dispatcherunhandledexception;
//当某个异常未被捕获时出现
appdomain.currentdomain.unhandledexception += currentdomain_unhandledexception;
//未被观察到的task多线程异常
taskscheduler.unobservedtaskexception += taskscheduler_unobservedtaskexception;
}
private void current_dispatcherunhandledexception(object sender, system.windows.threading.dispatcherunhandledexceptioneventargs e)
{
e.handled = true;
messagebox.show($"current_dispatcherunhandledexception:" + e.exception.message);
}
private void currentdomain_unhandledexception(object sender, unhandledexceptioneventargs e)
{
messagebox.show($"currentdomain_unhandledexception:" + (e.exceptionobject as exception).message);
}
private void taskscheduler_unobservedtaskexception(object sender, unobservedtaskexceptioneventargs e)
{
messagebox.show($"taskscheduler_unobservedtaskexception:" + e.exception.message);
}
}
以上就是本文的内容,希望以上内容可以帮助到您,如文中有不对之处,还请批评指正。
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论