AppDomain.Unload throws in Finalizer?

社会主义新天地 提交于 2019-12-22 05:21:59

问题


So here is the story so far, I have this worker thingy which uses an AppDomain to perform some task. The domain is expensive to setup and teardown. So I create a cache per-thread of WeakReference objects to the worker thingy like so:

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
}

The problem I'm having is that seems to always throw an exception in the call to AppDomain.Unload when GC collects:

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

So I'm thinking that's wierd, I know I don't have anything 'running' in that domain... Whats the deal? A bit of digging and trial and error I came up with this:

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

So my Questions are:

  1. Will AppDomain.Unload always fail from a Finalizer? Why?
  2. Am I going to experience anything 'undesirable' with the above workaround?

回答1:


AppDomains are unloaded by a separate CLR thread. That thread cannot run while the finalizer thread is running. You're getting the exception because the CLR notices that the unload thread isn't making progress. It never gets going because the finalizer thread is blocked on the Unload call.

Deadlock.

Your workaround indeed solves that deadlock. Doing the unloading explicitly instead of relying on a finalizer is the better approach here.



来源:https://stackoverflow.com/questions/4064749/appdomain-unload-throws-in-finalizer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!