为什么使用try {} finally {}和空try块?

我注意到在System.Threading.TimerBase.Dipose()方法有一个try{} finally{}块,但try{}是空的。

try{} finally{}使用try{} finally{}是否有任何价值?

http://labs.developerfusion.co.uk/SourceViewer/browse.aspx?assembly=SSCLI&namespace=System.Threading&type=TimerBase

 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] internal bool Dispose(WaitHandle notifyObject) { bool status = false; bool bLockTaken = false; RuntimeHelpers.PrepareConstrainedRegions(); try { } finally { do { if (Interlocked.CompareExchange(ref m_lock, 1, 0) == 0) { bLockTaken = true; try { status = DeleteTimerNative(notifyObject.SafeWaitHandle); } finally { m_lock = 0; } } Thread.SpinWait(1); // yield to processor } while (!bLockTaken); GC.SuppressFinalize(this); } return status; } 

来自http://blog.somecreativity.com/2008/04/10/the-empty-try-block-mystery/

这种方法防止一个Thread.Abort调用中断处理。 Thread.Abort的MSDN页面说:“在线程中止之前执行”未执行的finally块“。 所以为了保证你的处理完成,即使你的线程在你的线程中被Abort中断了,你也可以把所有的代码放在finally块中(另一种方法是在“catch”块中写代码请确定“尝试”之前的位置是否被“中止”中断,然后从此处继续)。

这是为了防止Thread.Abort中断一个进程。 这个方法的文档说:

在线程被中止之前,最终未执行的块被执行。

这是因为为了从错误中成功恢复,您的代码将需要自行清理。 由于C#没有C ++风格的析构函数,因此finallyusing块是确保这种清理可靠执行的唯一可靠方法。 请记住, using块由编译器变成这个:

 try { ... } finally { if(obj != null) ((IDisposable)obj).Dispose(); } 

在.NET 1.x中,有可能终止块会被中止。 这个行为在.NET 2.0中被改变了。

而且,空的try块永远不会被编译器优化。