¿Por qué usar try {} finally {} con un bloque try vacío?

Noté en System.Threading.TimerBase.Dipose() el método tiene un bloque try{} finally{} pero el try{} está vacío.

¿Hay algún valor en usar try{} finally{} con un bash vacío?

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

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

Esta metodología protege contra una llamada Thread.Abort que interrumpe el procesamiento. La página de MSDN de Thread.Abort dice que “los bloques finalmente no ejecutados se ejecutan antes de que se interrumpa el hilo”. Por lo tanto, para garantizar que su procesamiento termine incluso si el hilo se interrumpe en el medio por alguien que llama Abort en su hilo, puede colocar todo su código en el bloque finally (la alternativa es escribir código en el bloque “catch” para determine dónde estaba antes de que “intentar” se interrumpiera con Abortar y proceda desde allí si lo desea).

Esto es para protegerse contra Thread.Abort . Thread.Abort interrumpir un proceso. La documentación para este método dice que:

Los bloques finalmente no ejecutados se ejecutan antes de que se anule el hilo.

Esto se debe a que para recuperarse exitosamente de un error, su código deberá limpiarse por sí mismo. Como C # no tiene destructores de estilo C ++, finally y el using bloques es la única manera confiable de garantizar que dicha limpieza se realice de manera confiable. Recuerde que al using bloque se convierte en esto por el comstackdor:

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

En .NET 1.x, existía la posibilidad de que finally se abortara el locking. Este comportamiento fue cambiado en .NET 2.0.

Además, el comstackdor nunca optimiza los lockings try vacíos.