2010-02-02 28 views
221

Observé en System.Threading.TimerBase.Dipose() que el método tiene un bloque try{} finally{} pero el try{} está vacío.¿Por qué usar try {} finally {} con un bloque try vacío?

¿Hay algún valor en usar try{} finally{} con un intento 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; 
} 
+2

¿Qué hay para conseguir? ¿No leíste el útil comentario? – ChaosPandion

Respuesta

155

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

Esta metodología protege contra una llamada Thread.Abort interrumpir el procesamiento . La página MSDN de Thread.Abort dice que "los bloques finalmente no ejecutados se ejecutan antes de que se interrumpa el hilo ". Así que con el fin de garantía de que sus procesamiento acabados incluso si el hilo se abortado en el medio por alguien llamando Abortar en su hilo, que pueden lugar todo el código en el bloque finalmente (la alternativa es escribir código en el bloque "catch" para determinar donde estaba antes de "try" fue interrumpido por abortar y proceder desde allí si lo desea).

+5

¿Por qué no usar http://msdn.microsoft.com/en-us/library/system.threading.thread.begincriticalregion.aspx? –

+13

Porque no estaba disponible hasta .NET 2.0 –

+4

@ RobFonseca-Ensor: Porque 'Thread.BeginCriticalRegion()' no * evita * que un hilo sea abortado, sino que le dice al tiempo de ejecución que * si * un hilo se ha cancelado, entonces el estado global está corrupto, y todo el dominio de aplicación está a merced de la misericordia. – kkm

59

Esto es para evitar la interrupción de un proceso Thread.Abort. Documentation para este método dice que:

no ejecutadas por último secuencias se ejecutan antes de que se abortó el hilo.

Esto se debe a que para recuperarse correctamente de un error, su código tendrá que limpiarlo. Como C# no tiene destructores de estilo C++, los bloques finally y using son la única manera confiable de garantizar que dicha limpieza se realice de manera confiable. Recuerde que using bloque se convierte en esto por el compilador:

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

En 1.x NET, que había una posibilidad de que finally bloque conseguirá abortada. Este comportamiento fue cambiado en .NET 2.0.

Por otra parte, los bloques vacíos try nunca se optimizan por el compilador.

+0

Gracias por la información sobre el bloque de uso. – Stefan

Cuestiones relacionadas