代码之家  ›  专栏  ›  技术社区  ›  csharptest.net

AppDomain.Unload抛出终结器?

  •  7
  • csharptest.net  · 技术社区  · 14 年前

    到目前为止,我有一个工作线程,它使用一个AppDomain来执行一些任务。域的设置和拆卸成本很高。因此,我为每个WeakReference对象线程创建一个缓存到工作线程,如下所示:

    class Worker
    {
        [ThreadStatic]
        static Dictionary<string, WeakReference> _workers;
    
        public static Worker Fetch( ... ) { you get the idea }
    
        private AppDomain _domain;
        public Worker(...)
        {
            _domain = AppDomain.Create( ... );
        }
    
        ~Worker()
        { 
            AppDomain.Unload(_domain);
        }
    
        // bla bla bla
    }
    

    System.CannotUnloadAppDomainException: Error while unloading appdomain. (Exception from HRESULT: 0x80131015)"
    

    所以我想那是wierd,我知道在那个领域我没有任何东西在运行。。。怎么回事?经过一番挖掘和反复试验,我得出了这个结论:

        ~Worker()
        { 
            new Action<AppDomain>(AppDomain.Unload)
                .BeginInvoke(_domain, null, null);
        }
    

    所以我的问题是:

    1. AppDomain.Unload总是从终结器失败吗?为什么?
    1 回复  |  直到 10 年前
        1
  •  12
  •   Hans Passant    14 年前

    AppDomains由单独的CLR线程卸载。终结器线程正在运行时,该线程无法运行。你得到了异常,因为CLR注意到卸载线程没有进展。它永远不会运行,因为终结器线程在卸载调用时被阻塞。

    你的解决办法确实解决了僵局。在这里,显式地卸载而不是依赖终结器是更好的方法。