假设扔我有这样的代码:为什么ThreadAbortException不catch块
static void Main(string[] args)
{
var thread = new Thread(() =>
{
try
{
throw new InvalidOperationException();
}
catch (Exception)
{
Thread.Sleep(Timeout.Infinite);
}
});
thread.Start();
Thread.Sleep(TimeSpan.FromSeconds(1));
thread.Abort();
thread.Join();
}
它启动线程,那么线程进入在catch块睡眠之后,我们正试图中止线程。
中止方法必须引发ThreadAbortException。但是在catch块中它不会发生。 这是documented:
调用如果被 中止线程的代码保护的区域,如catch块中止可能会阻塞线程, finally块,或约束的执行区域。如果 调用中止的线程持有中止线程所需的锁定,则会发生死锁 。
我的问题是为什么。它为什么这样工作?因为在catch块中,我们可以提出任何异常和所有需要的作品。
UPDATE: 从link通过Jordão酒店。接受,因为这是最容易理解的澄清。
约束的执行区域的.NET Framework 2.0引入 约束的执行区域(CER),其中两个上 运行时和在显影剂施加限制。在被标记为CER的代码区域中,运行时限制不会抛出某些异常,这会阻止该区域在其整个 中执行。开发人员也可能在该地区执行的操作受到限制。这创建了一个框架和执行 机制来编写可靠的托管代码,使其成为.NET Framework 2.0的可靠性故事中的关键角色 。运行时间为 以应对其负担,它为CERs提供了两种便利。首先, 运行时将延迟在CER中执行的代码的线程中止。 换句话说,如果一个线程调用Thread.Abort来放弃当前在一个CER内执行的另一个线程 ,那么运行时不会中止目标线程的 ,直到执行离开CER。其次,运行时将尽可能快地准备CER,以避免 内存不足的情况。这意味着运行时将在代码区域的 JIT编译期间通常执行的所有操作都会执行 。它还将探测一定数量的免费堆栈空间来帮助消除堆栈溢出异常。通过预先执行此项工作,运行时可以更好地避免区域内可能发生的异常,并防止资源被适当清理 。要有效使用CER,开发人员应避免可能导致异步异常的某些操作。代码 受限于执行某些操作,包括显式分配,装箱,虚拟方法调用(除非虚拟方法调用的目标 已准备好),方法调用 通过反射,使用Monitor等。输入(或在C# 和为SyncLock在VisualBasic®lock关键字),在 COM对象isinst和castclass指令,通过透明代理字段访问,序列化 和多维数组访问。总之,核证减排量的代码运行之前移动 从你的代码的任何运行时引发的故障点的时间要么 (JIT在编译的情况下)的方式,或代码 完成后(线程中止)。但是,CERs确实会限制您可以编写的代码 。诸如不允许大多数分配 或对未准备目标的虚拟方法调用的限制是重要的, 意味着编写它们的高开发成本。这意味着核证减排量 不适合的通用代码的大机构,他们 应改为被认为是一种技术,以保证代码 小区域的执行。
这看起来像是一个bug,Abort()被忽略。发布到connect.microsoft.com –