サンプルコードは次のとおりです。
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
}
}
}
オブジェクトの存続期間にわたって使用されるコンストラクターで AppDomain を作成するクラスがあります。AppDomain を適切にクリーンアップしたいので、ファイナライザーで Unload を呼び出すことにしました。残念ながら、これにより CannotUnloadAppDomainException がスローされます。AppDomain.Unloadの MSDN ドキュメントには次のように記載されています。
場合によっては、Unload を呼び出すと、すぐに CannotUnloadAppDomainException が発生します。
どうしてこれなの?メンバー変数「ドメイン」は既にクリーンアップされていますか? そのクリーンアップには、AppDomain のアンロードが自動的に含まれますか? それとも、アクセスできない方法でまだ存在しますか? 私がすべきことはありますか、それともファイナライザーを安全にダンプできますか? (プロセスでオブジェクトが完全にクリーンアップされている限り、GC がいつオブジェクトを削除するかはあまり気にしません。)