2010-08-11 17 views
16

I finalizzatori sono garantiti per l'esecuzione in .NET a un certo punto (interruzioni di corrente di riserva e simili)? So come funziona GC e non è deterministico quando eseguiranno esattamente.I finalizzatori .net vengono sempre eseguiti?

(La ricerca non ha mostrato buone risposte, quindi sto aggiungendo questa domanda in attesa di un'unione con le risposte effettive non così facili da scoprire.A parte questo, conosco già la risposta e lo aggiungerò dopo alcuni giorni nel caso nessuno lo menzioni)

risposta

24

finalizzatori può effettivamente essere mai eseguito, come Raymond Chen explains. Un po 'strano che questa domanda viene chiesto durante la settimana annuale CLR, appena due giorni dopo aver spiegato :)

Per i più pigri, la (o meglio, uno) conclusione è:

Un correttamente - il programma scritto non può presumere che i finalizzatori verranno mai eseguiti.

Se ti stai chiedendo se puoi contare sui finalizzatori, questo è già tutto quello che devi sapere: non fare affidamento sui finalizzatori.

Come Raymond Chen afferma anche nel articolo collegato:

finalizzatori sono una rete di sicurezza, non è un mezzo primario per la bonifica delle risorse.

Se stai cercando come liberare risorse, dai un'occhiata al modello monouso.


un finalizzatore potrebbe non funzionare, per esempio, se:

  • Un altro finalizzatore genera un'eccezione.
  • Un altro finalizzatore richiede più di 2 secondi.
  • Tutti i finalizzatori insieme richiedono più di 40 secondi.
  • Un AppDomain blocca o viene scaricato (anche se è possibile aggirare questo con un finalizzatore critico (CriticalFinalizerObject, SafeHandle o qualcosa di simile)
  • No garbage collection si verifica
  • Il processo si blocca

(Nota: I valori temporali possono essere cambiati nel tempo, but were certainly true some time ago.)

Immagino che ci siano molte più cose che possono far sì che i finalizzatori non vengano mai eseguiti.La linea di fondo è, oltre alla citazione di Chen, che i finalizzatori sono un rete di sicurezza th a diminuire l'impatto dei bug, perché ad esempio le risorse vengono rilasciate a volte, che è meglio di mai, se si dimentica di farlo in modo esplicito.

+0

Puoi citare di più delle parti importanti? E sì, forse il richiedente non vedeva l'ora di trovare esattamente quel collegamento. ;) – mafu

+0

In realtà, dal momento che molte persone chiedono come possono fare affidamento sul comportamento del finalizzatore, penso che * * abbia * citato la singola parte più importante;) D'altra parte, anche le altre caselle nell'articolo potrebbero essere interessanti. – OregonGhost

+0

@OregonGhost: Sto comprendendo questo diritto: se 20 finalizzatori prendono ciascuno 1,95 secondi ciascuno, questo è hunky dory e tutto verrà eseguito - impiegando 39 secondi. Se uno prende 2,05 secondi, l'esecuzione di tutti gli altri viene saltata. Sembra piuttosto rotto. Piuttosto bruscamente interrompendo un finalizzatore che richiede più di 2 secondi, allo scopo di consentire ad altri di funzionare per il resto del timeout di 40 secondi, sarebbe una buona caratteristica. Ma le cose che scombussolano dopo due secondi sembrerebbero una disfunzione. – supercat

6

Se un finalizzatore genera un'eccezione, gli altri finalizzatori non verranno eseguiti.

È anche possibile eliminare i finalizzatori se si chiama SuppressFinalizer sull'oggetto.

Da MSDN (Object.Finalize):

Il metodo Finalize potrebbe non funzionare al completamento o potrebbe non funzionare affatto nelle seguenti circostanze eccezionali:

  • Altri blocchi Finalizer a tempo indeterminato (va in un ciclo infinito, cerca di ottenere un blocco che non può mai ottenere e così via). Poiché il runtime tenta di eseguire i finalizzatori fino al completamento, altri finalizzatori potrebbero non essere chiamati se un finalizzatore blocca indefinitamente.
  • Il processo termina senza dare al runtime la possibilità di eseguire la pulizia. In questo caso, la prima notifica del processo di esecuzione della terminazione è una notifica DLL_PROCESS_DETACH.
+0

Potresti aggiungere un sorgente per la parte "eccezione"? – mafu

+0

Nota che "entra in un loop infinito" fa, nell'implementazione CLR, significa "richiede più di due secondi", come spiegato qui: http://nitoprograms.blogspot.com/2009/08/finalizers-at-process- exit.html – OregonGhost

+0

@mafutrct - Vedi qui: http://stackoverflow.com/questions/1538630/exceptions-during-finalize-what-methodology-are-you-using-to-detect-garbage-co – Oded

Problemi correlati