2012-11-18 1 views
5

Я использую AppDomain, чтобы загружать сборки, а затем выгружать их.Ассембли не разгружаются после выгрузки AppDomain?

Тем не менее, у меня проблема очень серьезная. После того, как AppDomain выгружается - я все еще вижу в обработчике процессов, что некоторые сборки загружаются несколько раз! Почему есть остатки загруженных сборок? Не AppDomain.Unload освобождает всю загруженную память AppDomain?

Вы можете увидеть в прилагаемом изображении:

Всего AppDomains являются 3 (я создал 3 AppDomains в жизненном цикле текущего процесса)

AppDomains: 1 (В настоящее время только 1 AppDomain существует)

И по какой-то причине, как вы можете видеть в загруженной DLL секции сильфона - сборки загружаются несколько раз в процессе ..

Код:

AppDomain fetcherDomain = AppDomain.CreateDomain("StatusFetcher"); 
try 
{ 
    var fetcher = (LocalStatusFetcher)fetcherDomain.CreateInstanceFromAndUnwrap(Assembly.GetExecutingAssembly().CodeBase, typeof(LocalStatusFetcher).FullName); 
    //doing some other stuff that is not interesting... 
} 
finally 
{ 
    AppDomain.Unload(fetcherDomain); 
} 

И да, LocalStatusFetcher делает унаследовать MarshalByRefObject ...

enter image description here

+0

Возможно, вы также загружаете сборки в свой основной AppDomain. Кстати, разрешение изображения слишком низкое, и я ничего не вижу. –

+0

Я думал об этом, но это не так (проверено с помощью отладчика). Кроме того, сборки появляются не один раз, только когда они загружаются в несколько AppDomains. Что касается качества изображения - это stackoverflow, который делает это, если вы берете URL-адрес изображения и вставляете его на другую вкладку, вы сможете увидеть его в порядке. –

+0

Сборки, которые видны с вашего экрана, - это все сборки .NET Framework. Это происходит и с вашими сборками? –

ответ

2

Там очень высокая вероятность того, что узлы вы загружаете в чужом домене приложения в настоящее время кровоточили в текущий. Существует тонн способов, которыми это может случиться, но ваша проблема, в частности, проходит Assembly.GetExecutingAssembly().CodeBase до CreateInstanceFromAndUnwrap. Вызов Assembly.GetExecutingAssembly() загружает выполняемую в настоящее время сборку в текущий домен домена и передает .CodeBase объект . CreateInstanceFromAndUnwrap попытается загрузить целевую сборку (расположенную в пути приложения или в GAC) в целевой домен, прежде чем создавать целевой прокси. В настоящее время я не вижу ничего плохого в этом коде, кроме возможной проблемы с кровотечением.

Если у вас несколько доменов приложений, вы увидите несколько экземпляров сборки в контексте LoadFrom, потому что сборка , которая используется совместно с AppDomains, - это mscorlib.dll. Если я не понимаю ваш вопрос, я думаю, что вы видите, что это нормально.

+0

Текущая сборка, конечно же, уже загружена в текущий домен приложения, поэтому я не вижу, как вызов GetExecutingAssembly может быть проблематичным. кроме того, я знаю, что другой домен приложения будет загружать эти сборки, я не понимаю, почему он не освобождает их, когда это делается? Я не думаю, что то, что я вижу, является нормальным. Концепция домена приложения заключается в том, что после его выпуска все сборки, загруженные в него, также освобождаются ... –

+0

1. Как вы загружаете их в альтернативный домен приложения? 2. Вы ссылаетесь на загруженные сборки в любом контексте в текущем домене приложения? – Jduv

+0

Я ссылаюсь на них и использую их в текущем контексте. Это не проблема. Я ожидаю, что они будут загружены. Вопрос в том, почему они загружаются дважды? Я выгрузил другой AppDomain, они должны вернуться к загрузке только один раз. –