我在System.Threading.TimerBase.Dipose()
注意到该方法有一个try{} finally{}
块,但try{}
为空。
使用try{} finally{}
进行空尝试是否有任何价值?
[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;
}
答案 0 :(得分:163)
来自http://blog.somecreativity.com/2008/04/10/the-empty-try-block-mystery/:
这种方法可以防范a Thread.Abort调用中断了 处理。 MSDN页面 Thread.Abort说“未经执行 最后块在执行之前执行 线程被中止“。所以为了 保证您的处理 即使你的线程是完成的 某人在中间流产 你可以在你的线程上调用Abort 将所有代码放在finally中 块(替代方法是写 代码在“catch”块中确定 你在“尝试”之前的位置 被Abort打断并继续前进 如果你愿意的话。)
答案 1 :(得分:63)
这是为了防止Thread.Abort
中断进程。这个方法的Documentation表示:
在线程中止之前执行了未执行的finally块。
这是因为为了从错误中成功恢复,您的代码将需要自行清理。由于C#没有C ++样式的析构函数,finally
和using
块是确保可靠地执行此类清理的唯一可靠方法。请记住,编译器会将using
块转换为此内容:
try {
...
}
finally {
if(obj != null)
((IDisposable)obj).Dispose();
}
在.NET 1.x中,finally
块可能会被中止。在.NET 2.0中,此行为已更改。
此外,空try
块永远不会被编译器优化掉。