【发布时间】:2013-08-02 21:13:35
【问题描述】:
我读过的所有内容都声称线程中止将在从 ThreadAbortException 结束之前执行 finally 块。我想确认这一点,以便我可以计划如何处理一些可以无限期挂起的第 3 方代码。然而,以下测试让我感到困惑:
public void runTest(DateTime deadline)
{
testThread = new Thread(() =>
{
try
{
Console.WriteLine("test thread started at " + DateTime.Now.ToShortTimeString());
while (true) { }
}
finally
{
Console.WriteLine("test thread entered FINALLY at " + DateTime.Now.ToShortTimeString());
while (true) { }
}
});
testThread.Start();
while (testThread.IsAlive && deadline.Subtract(DateTime.Now).TotalSeconds > 0)
{
Console.WriteLine("main thread while loop " + DateTime.Now.ToShortTimeString());
Thread.Sleep(10000);
}
if (testThread.IsAlive)
testThread.Abort();
Console.WriteLine("main thread after abort call " + DateTime.Now.ToShortTimeString());
}
我在运行时发现控制台从未提及进入 finally 块。应用程序在 .abort 调用之后继续运行,就好像根本没有 finally 块一样。难道我做错了什么?在到达控制台的最终写入之前控制是否应该传递给 finally 块,或者执行顺序是否仍然是 finally 在单独线程中或其他什么事实的函数?
【问题讨论】:
-
我运行了代码,得到了
test thread entered FINALLY at 3:21 PM。 -
未尝试,但我怀疑代码在调试和发布/无调试器附加配置之间的行为会有所不同,因为无限循环可能会被 JIT 到发布构建中无法中断的内容。
-
打电话给
Thread.Abort就像用枪击中司机的头部来停车一样。汽车会停下来,但不知道在此期间会发生什么。您真的不应该永远需要致电Thread.Abort。如果你这样做了,那么你需要重新审视你的应用程序的设计。 -
几乎每个人都在我吃午饭的时候发现了这个问题。 finally 不会被跳过,它只是在另一个线程中,因此在 .abort 调用之后不一定会立即执行。我错误地认为 .abort 将是一个串行执行,它直接进入 finally 块,然后返回主线程。测试线程有时在主线程恢复后的几秒钟内实际上并没有结束。
标签: c# multithreading abort finally