不得惭愧的说,之前我一直认为多线程中线程的未处理异常对程序 Main Thread 毫无影响。我觉得我之所以有这样的认识有以下几个原因(不是找借口哈):
如果不去究其原因,就只能想微软常说的那样“it was not a problem, that was by design.”, 但确实,有些东西预先就是这么设计的。
但如果你以为记住这些API的表现就行了,在以后的使用中就不会有什么问题了,那就太天真了,举个栗子:上边那些works good的API在不同版本.NET Framework下任有不同的表现。
所以,在那些只装有.NET framework 4.0的机器上,我们的应用程序在GC回收时,若发现有未处理的线程异常,则会终止应用程序。
以上,我都全部验证过,的确如此,之前一直没注意这个,直到有一天用户抛给我一个bug.但如果.NET Framework一直保持Update,那么,这将不会是一个问题。
那么,如果我们想要在一个地方,统一处理所有的Unhandled Exception,如何做呢?
我们可以订阅TaskScheduler.UnobservedTaskException全局事件,该事件即可作为那些未处理异常的Handler,标记异常已被处理以改变.NET 4.0的默认行为(terminates the process).
所以,只要涉及到多线程,就会增加程序的复杂度,就算你做好了多线程资源同步等等常规性的问题,总避免不了出现一些隐式的问题,直到发现它那天为止。
但也不是无法完全避免,比如只要涉及到有新的线程开销了,是否需要特别关注,线程内部的异常要怎么处理,如果做好了这样的“内聚”工作,相信线程间、模块间的依赖也就消失了,那么,自然问题也就少了。