Voici quelques exemples de code:Pourquoi l'erreur AppDomain.Unload() dans le finaliseur?
using System;
namespace UnloadFromFinalizer
{
class Program
{
static void Main(string[] args)
{
Program p = new Program();
}
AppDomain domain;
Program()
{
this.domain = AppDomain.CreateDomain("MyDomain");
}
~Program()
{
AppDomain.Unload(this.domain);//<-- Exception thrown here
}
}
}
J'ai une classe qui crée un AppDomain dans le constructeur à utiliser sur la durée de vie de l'objet. Je voudrais nettoyer correctement l'AppDomain, alors j'ai pensé que j'appellerais Décharger dans le finaliseur. Malheureusement, cela provoque une exception CannotUnloadAppDomainException. La documentation MSDN pour AppDomain.Unload notes:
Dans certains cas, l'appel Unload provoque une CannotUnloadAppDomainException immédiate, pour un grand si elle est appelée dans un finaliseur.
Pourquoi est-ce? La variable membre "domain" est-elle déjà nettoyée? Ce nettoyage inclut-il automatiquement le déchargement de l'AppDomain ou existera-t-il encore de manière inaccessible? Y a-t-il quelque chose que je devrais faire, ou puis-je sauvegarder le finalizer en toute sécurité? (Je ne me soucie pas vraiment quand le GC se débarrasse de mon objet tant qu'il est entièrement nettoyé dans le processus.)
Ceci est juste un exemple de programme. Dans ma vraie application, mon objet ne vit pas dans Main et pourrait être récupéré avant que mon application ne soit terminée. Je suppose que je voulais juste m'assurer que le GC nettoierait correctement l'AppDomain par lui-même. Cela semble être le cas. – Nogwater
Plus généralement, le schéma de finalisation de choses qui sont déjà des objets gérés me semble suspect. Je pense normalement à un finaliseur comme quelque chose qui ferme une poignée du noyau, ou quelque chose comme ça. Terminez-vous habituellement les objets gérés? –
Non. C'était en fait ma première fois à essayer des finaliseurs. Je ne savais pas que l'AppDomain serait entièrement géré. Je suppose que si ce n'était pas, il implémenterait IDisposable. – Nogwater