2010-02-02 14 views
221

Ho notato nel System.Threading.TimerBase.Dipose() il metodo ha un blocco try{} finally{} ma lo try{} è vuoto.Perché usare try {} finally {} con un blocco try vuoto?

C'è qualche valore nell'uso di try{} finally{} con una prova vuota?

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

Cosa c'è da ottenere? Non hai letto il commento utile? – ChaosPandion

risposta

155

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

Questa metodologia protezioni contro una chiamata Thread.Abort interrompere il trattamento . La pagina MSDN di Thread.Abort dice che "I blocchi ineseguiti vengono eseguiti prima che il thread venga interrotto". Quindi, al fine di garanzia che i vostri l'elaborazione finiture, anche se il filo è interrotta a metà da qualcuno chiamando Abort sul tuo thread, è possibile posto tutto il codice nel blocco finalmente (l'alternativa è quello di scrivere codice nel blocco "catch" per determinare dove eri prima "try" era interrotto da Abort e procedere da lì se lo si desidera).

+5

Perché non utilizzare http://msdn.microsoft.com/en-us/library/system.threading.thread.begincriticalregion.aspx? –

+13

Perché non era disponibile fino a .NET 2.0 –

+4

@ RobFonseca-Ensor: Poiché 'Thread.BeginCriticalRegion()' non * impedisce * l'interruzione di un thread, indica al runtime che * if * un thread viene interrotto, quindi lo stato globale è corrotto e l'intero appdomain dipende da un omicidio premuroso. – kkm

59

Questo per evitare Thread.Abort interrompere un processo. Documentation per questo metodo dice:

I blocchi infine non eseguiti vengono eseguiti prima che il thread venga interrotto.

Ciò è dovuto al fatto che per ripristinare correttamente da un errore, il codice dovrà essere ripulito automaticamente. Poiché C# non ha distruttori in stile C++, i blocchi finally e using sono l'unico modo affidabile per garantire che tale ripulitura venga eseguita in modo affidabile. Ricordate che using blocco si trasforma in questo dal compilatore:

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

In 1.x .NET, c'era la possibilità che finally blocco otterrà interrotta. Questo comportamento è stato modificato in .NET 2.0.

Inoltre, i blocchi try vuoti non vengono mai ottimizzati dal compilatore.

+0

Grazie per l'approfondimento sul blocco in uso. – Stefan

Problemi correlati