In primo luogo, leggiamo su CriticalFinalizerObject in MSDN, si legge, che:
In classi derivate dalla Critica classe alFinalizerObject, Common Language Runtime (CLR) garantisce che a tutti i codici di finalizzazione critici verrà data l'opportunità di eseguire, a condizione che il finalizzatore segua le regole per un CER, anche in situazioni in cui il CLR forzatamente scarica un dominio applicazione o interrompe un filo.
La parola principale qui è UNLOAD.
In secondo luogo, leggiamo MSDN di nuovo, questa volta sulle eccezioni in thread gestiti:
Se queste eccezioni sono non gestita nel thread principale, o in fili che sono entrate nel runtime da codice non gestito, che procede normalmente, con conseguente terminazione dell'applicazione.
La parola principale è TERMINAZIONE.
Così, quando c'è un'eccezione non gestita nel thread principale - l'app termina, ma CriticalFinalizerObject aiuta solo a scaricare il Dominio.
Per esempio, CriticalFinalizerObject può aiuta in tale situazione:
// Create an Application Domain:
AppDomain newDomain = AppDomain.CreateDomain("NewApplicationDomain");
// Load and execute an assembly:
newDomain.ExecuteAssembly(@"YouNetApp.exe");
//Unload of loaded domain
AppDomain.Unload(newDomain);
questa è una situazione, in cui è stato scaricato il dominio e CriticalFinalizerObject garantirvi, che il finalizzatore verrà chiamato.
Nella tua situazione con terminazione di applicazione che si può provare a iscriversi a
AppDomain.CurrentDomain.UnhandledException
e finalizzare manualmente gli oggetti.
UPD: Jeffrey Richter nel suo libro "CLR via C#", ha scritto su CriticalFinalizerObject, che è per le situazioni in cui si invia il codice, ad esempio a SQLServer, che può essere eseguito C# come procedure. In tal caso, CriticalFinalizerObject ti aiuta a pulire il tuo oggetto, se SQLServer scaricherà il dominio della tua libreria. Anche CriticalFinalizerObject è per le situazioni in cui è necessario nel finalizzatore dell'oggetto chiamare il metodo di un altro oggetto, poiché CriticalFinalizerObject garantisce che il suo finalizzatore verrà chiamato dopo i finalizzatori di tutti gli oggetti non CriticalFinalizerObject.
Grazie per la risposta dettagliata! Direi che parole come "terminato" o "scaricato" non sono molto ben definite in questi documenti MS. Nel senso comune, avere qualcosa "terminato" non significa necessariamente che non sarà "scaricato", anche se come vediamo qui non è così ... – IlyaP
Ho aggiunto alcuni aggiornamenti per rispondere da "CLR via C#" – igofed