Получилась следующая ситуация...
1) Создаем в приложении домен.
2) Загружаем в него через DoCallBack
сборку Assembly.Load(...)
3) Из главного домена достаем сборки ранее созданного и например, показываем их имена.
4) Смотрим какие сборки есть в главном домене, а конкретней - там появилась эта сборка которую мы загрузили в другой домен.
То есть, загружая сборку в другой домен, если обратиться с методу GetAssemblies
, загруженные сборки появляются и в основном домене, при этом они не просто туда переносятся, они копируются - их можно использоваться в обоих доменах.
Если зациклить данный процесс и наблюдать за памятью, то видно что она растет, значит сборки загружаются по новой в память каждый раз.
Самый главный вопрос, почему? Как избавиться от переноса сборки в основной домен? Тут даже не в памяти дело, а в том что основной домен держит референс на сборку и не дает её удалить, например. А инфу как-то вытаскивать надо.
class Program
{
static void Main ( string [ ] args )
{
var appDomain = AppDomain.CreateDomain("TestDomain");
appDomain.DoCallBack(LoadModule);
var assembly = appDomain.GetAssemblies().Single( t => t.GetName().Name == "TestModule" );
foreach ( var assembly1 in AppDomain.CurrentDomain.GetAssemblies() )
{
Console.WriteLine( assembly1.FullName );
}
}
private static void LoadModule()
{
Assembly.Load( "TestModule" );
}
}
Существует две возможности передать объект через границу домена приложения:
System.MarshalByRefObject
. При этом все вызовы методов на прокси объекте автоматически перенаправляются в домен приложения, которому принадлежит исходный объект.При этом класс System.AppDomain
наследует от System.MarshalByRefObject
, в то время как класс System.Reflection.Assembly
нет. То есть вызов appDomain.GetAssemblies()
в Вашем коде будет перенаправлен в дополнительный домен приложения, после чего результат его работы (Assembly[]
) необходимо будет передать в основной домен приложения: сериализовать в дополнительном домене и десериализовать в основном домене. Данная передача Assembly
объектов в основной домен приложения и приводит к загрузке в него сборок.
Чтобы избежать загрузки сборок в основной домен, не передавайте в него объекты, для десериализации которых необходимо загрузить сборку. Как то System.Reflection.Assembly
объект, представляющий сборку, System.Type
объект, представляющий любой тип из сборки, экземпляр любого типа из сборки.
Например имена сборок можно извлекать в дополнительном домене приложения, а в основной передавать только строки:
using System;
using System.Linq;
using System.Reflection;
class Program
{
static void Main ( string [ ] args )
{
var appDomain = AppDomain.CreateDomain("TestDomain");
appDomain.DoCallBack(LoadModule);
var worker = (Worker)appDomain.CreateInstanceAndUnwrap(typeof(Worker).Assembly.FullName, typeof(Worker).FullName);
foreach ( var assemblyFullName1 in worker.GetAssembliesFullName() )
{
Console.WriteLine( assemblyFullName1 );
}
Console.WriteLine();
foreach ( var assembly1 in AppDomain.CurrentDomain.GetAssemblies() )
{
Console.WriteLine( assembly1.FullName );
}
}
private static void LoadModule()
{
Assembly.Load( "TestModule" );
}
}
class Worker : MarshalByRefObject {
public string[] GetAssembliesFullName() {
return AppDomain.CurrentDomain.GetAssemblies().Select(a => a.FullName).ToArray();
}
}
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Всем доброго времени суток, помогите пожалуйста разобратьсяСоздал Бота залил его на хостинг somee подключил к bot framework на сайте, при нажатии...
Доброго времени сутокВопрос следующий: как мне остановить показ анимации при помощи элемента Animator? При реализации возникает проблема, поскольку...
Есть программа, которая создает несколько (2-8) AwesomiumWindows