AppDomain.Unload выдает в финализатор? - PullRequest
7 голосов
/ 31 октября 2010

Итак, вот история, у меня есть эта рабочая штука, которая использует 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
}

Проблема, с которой я сталкиваюсь, заключается в том, что, похоже, всегда выдается исключение при вызове AppDomain.Unload при сборе GC: * ​​1004 *

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

Так что я думаю, что это странно, я знаю, что у меня ничего не "работает" в этой области ... В чем дело? Немного покопавшись и методом проб и ошибок я придумал это:

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

Итак, мои вопросы:

  1. Будет ли AppDomain.Unload всегда выходить из финализатора? Почему?
  2. Собираюсь ли я испытать что-либо «нежелательное» с вышеописанным обходным путем?

1 Ответ

12 голосов
/ 31 октября 2010

Домены приложений выгружаются отдельным потоком CLR. Этот поток не может работать во время работы потока финализатора. Вы получаете исключение, потому что CLR замечает, что поток выгрузки не прогрессирует. Он никогда не запускается, потому что поток финализатора блокируется при вызове Unload.

Тупик.

Ваш обходной путь действительно устраняет этот тупик. Явная выгрузка вместо того, чтобы полагаться на финализатор, является лучшим подходом здесь.

...