2010-02-02 2 views
221

Я заметил в System.Threading.TimerBase.Dipose() метод имеет блок try{} finally{}, но try{} пуст.Зачем использовать 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

Что нужно получить? Разве вы не читали полезный комментарий? – ChaosPandion

ответ

155

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

Эта методика охранники против Thread.Abort вызова прерывания обработки. Страница MSDN для Thread.Abort говорит, что «Unexecuted окончательные блоки выполняются до того, как поток прерван». Поэтому для того, чтобы гарантии, что ваша обработка заканчивается, даже если ваш поток прерван в середине кто-то вызывающих Прервать на вашу тему, вы можете разместить весь код в наконец блоке (альтернатива, чтобы написать код в блоке «catch», чтобы определить , где вы были до «попытки», было прервано Abort и исходить из , если вы хотите).

+5

Почему бы не использовать http://msdn.microsoft.com/en-us/library/system.threading.thread.begincriticalregion.aspx? –

+13

Поскольку это было недоступно до .NET 2.0 –

+4

@ RobFonseca-Ensor: Поскольку 'Thread.BeginCriticalRegion()' не * предотвращает * поток от прерывания, скорее сообщает время выполнения, что * if * поток прерывается, тогда глобальное государство является коррумпированным, и весь appdomain - это убийство по милости. – kkm

59

Это для защиты от 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 блоки никогда не будут оптимизированы компилятором.

+0

Спасибо за понимание использования блока. – Stefan

Смежные вопросы