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

时间:2010-02-02 17:15:26

标签: c# .net

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

使用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;
}

2 个答案:

答案 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 ++样式的析构函数,finallyusing块是确保可靠地执行此类清理的唯一可靠方法。请记住,编译器会将using块转换为此内容:

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

在.NET 1.x中,finally块可能会被中止。在.NET 2.0中,此行为已更改。

此外,空try块永远不会被编译器优化掉。