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

Sam*_*eff 235 .net c#

我注意到在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;
}
Run Code Online (Sandbox Code Playgroud)

dan*_*ben 166

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

此方法可防止Thread.Abort调用中断处理.Thread.Abort的MSDN页面说"在线程中止之前执行了未执行的finally块".因此,为了保证即使你的线程是由某人呼吁中止对你的线程在中间中止的处理完成后,你可以把所有的代码在finally块(另一种方法是写在"catch"块码在"尝试"被中止中断之前确定您的位置,如果您愿意,可以从那里继续.

  • 因为直到.NET 2.0才能使用它 (15认同)
  • @HansPassant:`BeginCriticalSection()`在.NET 1.x中确实不存在,但是没有因果关系,你暗示*因为*.事实上,在.NET 1.x中,即使是`finally`块也可能被线程中止中断.这些机制有不同的用途:在`finally`中工作可以防止在代码中途中止,而`BeginCriticalSection()`只向运行时声明全局状态存在风险. (8认同)
  • 为什么不使用http://msdn.microsoft.com/en-us/library/system.threading.thread.begincriticalregion.aspx? (6认同)
  • @ RobFonseca-Ensor:因为`Thread.BeginCriticalRegion()`不会*阻止*线程被中止,而是告诉运行时*如果*线程被中止,则全局状态已损坏,并且整个appdomain都是安乐死. (5认同)

Ant*_*lev 63

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

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

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

try {
    ...
}
finally {
    if(obj != null)
        ((IDisposable)obj).Dispose();
}
Run Code Online (Sandbox Code Playgroud)

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

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