我刚刚读完了《C# 4.0 in a Nutshell》(O'Reilly出版)这本书,我认为它是一本非常适合想转换到C#的程序员的好书,但是它让我感到困惑。我的问题是using
语句的定义。根据这本书(第138页),
using (StreamReader reader = File.OpenText("file.txt")) {
...
}
精确等价于:
StreamReader reader = File.OpenText("file.txt");
try {
...
} finally {
if (reader != null)
((IDisposable)reader).Dispose();
}
假设这是真的,而且这段代码在一个单独的线程中被执行。这个线程现在被 thread.Abort()
中止,因此抛出了一个 ThreadAbortException
,并且假设线程在初始化读取器之后、进入 try..finally
子句之前正好停止。这意味着读取器没有被处理!
一种可能的解决方案是这样编码:
StreamReader reader = null;
try {
reader = File.OpenText("file.txt");
...
} finally {
if (reader != null)
((IDisposable)reader).Dispose();
}
这将是“可中止安全”的。
现在我的问题是:
- 书的作者是否正确,
using
语句不是可中止安全的,还是他们错了,它的行为类似于我的第二个解决方案? - 如果
using
等同于第一种情况(不可中止安全),为什么要在finally
中检查null
? - 根据该书(第856页)的说明,
ThreadAbortException
可以在托管代码中的任何地方抛出。但也许有例外情况,第一种情况毕竟是可中止安全的吗?
编辑:我知道使用thread.Abort()
不被视为良好的实践。我感兴趣的纯粹是理论上的: using
语句的确切行为是什么?
Dispose
调用之前的finally
块中出现ThreadAbortException
,会发生什么? - liorithread.Abort
方法的行为就像怀疑汽车气囊是否真正起作用一样,如果你需要知道,那么你已经有了更大的问题。请注意,本翻译力求通俗易懂,且未改变原意。 - Marc Gravell