根据MSDN,AppDomain.Unload导致卸载AppDomain中的所有线程抛出线程中止异常。
域中的线程使用Abort方法终止,该方法 在线程中抛出ThreadAbortException。虽然线程 应该立即终止,它可以继续执行 finally子句中不可预测的时间量。 - 来自MSDN
所以我的理解是每次我在任何预期在这个AppDomain中运行的代码编写代码时,我都希望线程中止可以随时在任何线程上发生。这是真的? 所有代码都应该假设可以随时抛出ThreadAbortException吗?
实际上这实际上是elimates catch(Exception ex)因为它会捕获ThreadAbortException并尝试处理它,通常是通过记录一个真的不应该记录的错误(因为卸载AppDomain不是'真的是一个例外)。
为避免不必要的异常处理/错误记录,是否还需要考虑其他因素?
答案 0 :(得分:5)
你几乎可以随时了解TAE的可能性。我唯一要做的就是你的代码应该已经用这种方式编写了 - 在处理具有可靠性要求的数据时,你应该在硬件故障,操作错误,OOM等情况下使用事务或其他补偿机制。 - 其中任何一个都不是AppDomain关闭方案所特有的。
最后,您应该知道可以捕获TAE并在catch块中执行补偿代码。对他们来说唯一特别的事情就是他们会在捕获后立即重新开始,所以你不能吞下"吞下"他们。您可以使用Thread.ResetAbort()
来抑制它们,但在这种情况下可能没有达到预期的效果。
我们所有的代码都是这样的:
public void Foo() {
try {
Do.Some.Stuff();
} catch (Exception ex) {
Console.Out.WriteLine("Oh noes!");
}
}
是的,catch块将捕获所有 1 ,包括TAE和OOM。
这里要记住的是,对于上述所有例外情况,世界基本上已经结束。您应该关心的是,您处理的任何交易敏感数据都不会丢失或处于不良状态,这就是为什么我们通常会将交易安全I / O等事务留给微软和Oracle的聪明人都在编写数据库。例如,如果您的代码正在执行平面文件I / O,您需要确定永远不会使文件处于错误状态,那么您应该以非常全面的方式考虑故障模式 - 喜欢"当这个文件被半写时电源消失会发生什么?"
1 唯一的例外是StackOverflow exceptions generally cannot be caught。这是.NET 2.0的一个变化。
答案 1 :(得分:1)