如何防止后台线程抛出的异常让程序崩溃退出
2017-10-21 16:32
567 查看
如果你的程序抛了异常,你是怎么处理的呢?等待程序崩溃退出?还是进行补救?
如果是做 UI 开发,很容易就找到
WPF 和 Windows Forms 都是微软的框架,为了照顾初学者,微软会默认每一个开发者都不会正确地处理异常。于是在异常发生之后,微软 Windows 会假设开发者并不知道如何应对以便让应用程序正常工作,就擅自将应用程序进程结束掉,以便防止应用程序自己内部产生奇怪的状态和错误,避免对系统环境造成不可逆的严重后果。
能够写出异常处理代码的开发者,微软会默认他们懂了异常处理。
写出了监听
还有一个事件
在这个事件中,有一个属性
但还是要照顾更高级的开发者的,于是祭出新的配置——
在
加上了这个配置之后,
既然你通过这个配置节点于微软达成了契约,你就需要好好地在
Exceptions in Managed Threads - Microsoft Docs
如果是做 UI 开发,很容易就找到
Dispatcher.UnhandledException事件,然后在事件中进行补救。如果补救成功,可以设置
e.Handled = true来阻止异常继续让程序崩溃退出。但是,如果是后台线程抛出了异常呢?并没有
Dispatcher可以用。所以我们就束手就擒让程序自己退出吗?
WPF 和 Windows Forms 都是微软的框架,为了照顾初学者,微软会默认每一个开发者都不会正确地处理异常。于是在异常发生之后,微软 Windows 会假设开发者并不知道如何应对以便让应用程序正常工作,就擅自将应用程序进程结束掉,以便防止应用程序自己内部产生奇怪的状态和错误,避免对系统环境造成不可逆的严重后果。
能够写出异常处理代码的开发者,微软会默认他们懂了异常处理。
写出了监听
Dispatcher.UnhandledException事件的开发者,微软会认为他们已经学会了如何在 UI 线程中处理异常。于是允许开发者设置
e.Handled = true来标记异常已被正确处理,程序可以不用退出了。
还有一个事件
Appdomain.CurrentDomain.UnhandledException,然而这个事件却并不允许开发者标记
e.Handled = true。因为微软认为,应用程序域中所有的线程发生异常都会进入这个事件中,大多数开发者都不明白这些线程这些异常是怎么回事,所以不认为这些开发者具备正确处理这些异常的能力。比如 WPF 的触摸模块发生了异常,开发者知道如何恢复吗?并不知道,还不如结束掉程序然后重启呢!
在这个事件中,有一个属性
IsTerminating指示是否应用程序正因为这次异常准备退出,不过开发者并不能拿这个属性做些什么。
但还是要照顾更高级的开发者的,于是祭出新的配置——
legacyUnhandledExceptionPolicy!
在
app.config文件的
<runtime>节点中添加如下代码:
<legacyUnhandledExceptionPolicy enabled="1"/>
加上了这个配置之后,
Appdomain.CurrentDomain.UnhandledException事件的
IsTerminating就变成了
false啦!也就是说,程序并不会因为这次的异常而崩溃退出。
既然你通过这个配置节点于微软达成了契约,你就需要好好地在
Appdomain.CurrentDomain.UnhandledException事件中写好异常的恢复逻辑。如果不好好恢复,小心有些致命的异常会导致你的程序出现雪崩式的错误,最终 Windows 还是会通过
CorruptedStateException把你干掉的!
参考资料
c# - How to prevent an exception in a background thread from terminating an application? - Stack OverflowExceptions in Managed Threads - Microsoft Docs
相关文章推荐
- Android 通过Application捕获全局异常,防止程序崩溃退出
- exe崩溃用windbgattach后有宝贵现场,可看程序退出线程等,千万不要清屏
- 如何在程序异常退出前输出当前进程的堆栈信息 Backtraces
- Android 后台线程弹对话框导致程序崩溃(is not valid; is your activity running)(dialog总是牺牲)
- 线程不同步的原因,如何同步,简单的防止程序多开
- 如何使用MAP文件找到程序崩溃时源码是哪行异常
- 线程最后退出的时候抛出异常
- c# Linq Where 抛出异常 导致 程序崩溃
- MFC 程序崩溃自动重启 和 未捕获到的异常写退出栈
- 如何终止一个无限循环线程和 程序退出时销毁线程
- Java中主线程如何捕获子线程抛出的异常
- c# Linq Where 抛出异常 导致 程序崩溃
- IOS 如何退出后台执行程序
- C#中,退出窗口的时候如何干干净净把程序中的线程也干净的退出
- Java编程时主线程如何捕获子线程抛出的异常
- C++抛出异常时无法捕捉到异常,致使程序崩溃
- Node.js进程守护,防止程序崩溃自动退出
- 用户按下home键时如何退出程序而不是在后台挂起
- 如何在程序异常或者崩溃时产生一个dump文件
- C# 开发技巧]如何防止程序多次运行 线程 进程