代码之家  ›  专栏  ›  技术社区  ›  Samuel Neff

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

  •  231
  • Samuel Neff  · 技术社区  · 15 年前

    我注意到 System.Threading.TimerBase.Dipose() 该方法具有 try{} finally{} 阻止,但是 try{} 是空的。

    使用有什么价值吗 最后试试{} 一次空的尝试?

    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 回复  |  直到 9 年前
        1
  •  163
  •   DixonD    9 年前

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

    这种方法可以防止 thread.abort调用中断 处理。MSDN页,共页 thread.abort表示未执行 最后在 线程被中止。所以为了 保证你的处理 即使你的线是 中途被人流产 在线程上调用abort,可以 把你所有的代码放在最后 块(另一种方法是 要确定的“catch”块中的代码 你以前去过的地方 中断并继续 如果你愿意的话。

        2
  •  63
  •   Anton Gogolev    15 年前

    这是为了防范 Thread.Abort 中断进程。 Documentation 对于这种方法来说:

    未执行的finally块在线程中止之前执行。

    这是因为为了成功地从错误中恢复,您的代码需要在自身之后进行清理。因为C语言没有C++风格的析构函数, finally using 块是确保可靠执行此类清理的唯一可靠方法。记住这一点 使用 块由编译器转换为:

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

    在.net 1.x中,有可能 最后 块将被中止。此行为在.NET 2.0中已更改。

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