- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания ЯЗЫК ПРОГРАММИРОВАНИЯ С# 2005 И ПЛАТФОРМА .NET 2.0. 3-е издание - Эндрю Троелсен
Шрифт:
Интервал:
Закладка:
public static void PrintAllAssembliesInAppDomain(ApsDomain ad) {
Assembly[] loadedAssemblies = ad.GetAssemblies();
Console.WriteLine("*** Компоновочные блоки в рамках {0} ***n", ad.FriendlyName);
foreach (Assembly a in loadedAssemblies) {
Console.WriteLine("-› Имя: {0}", a.GetName().Name);
Console.WriteLine("-› Версия: {0}n", a.GetName().Version);
}
}
Теперь обновим метод Main(), чтобы перед вызовом PrintAllAssembliesInAppDomain() получить ссылку на текущий домен приложения, используя свойство AppDomain.CurrentDomain.
Чтобы сделать пример более интересным, метод Main() открывает окно сообщения Windows Forms (для этого среда CLR должна загрузить компоновочные блоки System.Windows.Forms.dll, System.Drawing.dll и System.dll, так что не забудьте установить ссылки на эти компоновочные блоки и соответственно изменить набор операторов using).
static void Main(string[] args) {
Console.WriteLine("***** Чудесное приложение AppDomain *****n");
// Чтение информации для текущего AppDomain.
AppDomain defaultAD= AppDomain.CurrentDomain;
MessageBox.Show(''Привет");
PrintAllAssembliesInAppDomain(defaultAD);
Console.ReadLine();
}
На рис. 13.6 показан соответствующий вывод (номера версий у вас могут быть другими).
Рис. 13.6. Перечень компоновочных блоков в рамках текущего домена приложений
Программное создание новых доменов приложения
Напомним, что один процесс может содержать множество доменов приложения, И хотя вам в программном коде вряд ли понадобится вручную создавать домены приложения, вы имеете возможность сделать это с помощью статического метода CreateDomain(). Нетрудно догадаться, что метод AppDomain.CreateDomain() перегружен. Вы, по крайней мере, должны указать понятное имя нового домена приложения, как показано ниже.
static void Main(string[] args) {
…
// Создание нового AppDomain в рамках текущего процесса.
AppDomain anotherAD = AppDomain.CreateDomain("SecondAppDomain");
PrintAllAssembliesInAppDomain(anotherAD);
Console.ReadLine();
}
Если выполнить приложение теперь (рис. 13.7), вы увидите, что компоновочные блоки System.Windows.Forms.dll, System.Drawing.dll и System.dll будут загружены только в рамках домена приложения, созданного по умолчанию. Это может показаться нелогичным для тех. кто имеете опыт программирования с использованием традиционных подходов Win32 (скорее, оба домена приложения должны иметь доступ к одному и тому же множеству компоновочных блоков). Напомним, однако, о том. что компоновочный блок загружается в рамки домена приложения а не в рамки непосредственно самого процесса.
Рис. 13.7. Один процесс с двумя доменами приложения
Далее, обратите внимание на то, что домен приложения SecondAppDomain автоматически получает свою собственную копию mscorlib.dll, поскольку этот ключевой компоновочный блок автоматически загружается средой CLR для каждого домена приложения. Это порождает следующий вопрос "Как можно программно загрузить компоновочный блок в домен приложения?" Ответ: с помощью метода АррDomain.Load() (или, альтернативно, с помощью AppDomain.executeAssembly()). В предположении, что вы скопировали CarLibrary.dll в каталог приложения AppDomainManipulator.exe, вы можете загрузить CarLibrary.dll в домен приложения SecondAppDomain так.
static void Main(string[] args) {
Console.WriteLine("***** Чудесное приложение AppDomain *****n");
…
// Загрузка CarLibrary.dll в новый AppDomain.
AppDomain anotherAD = AppDomain.CreateDomain("SecondAppDomain");
anotherAD.Load("CarLibrary");
PrintAllAssembliesInAppDomain(anotherAD);
Console.ReadLine();
}
Чтобы закрепить понимание взаимосвязей между процессами, доменами приложения и компоновочными блоками, рассмотрите рис. 13.8, на котором представлена диаграмма внутреннего устройства только что построенного процесса AppDomainManipulator.exe.
Рис. 13.8. Схема функционирования процесса AppDomainManipulator.exe
Программная выгрузка доменов приложения
Важно понимать, что среда CLR не позволяет выгружать отдельные компоновочные блоки .NET. Однако, используя метод AppDomain.Unload(), вы можете избирательно выгрузить домен приложения из объемлющего процесса. При этом домен приложения выгрузит по очереди каждый компоновочный блок.
Напомним, что тип AppDomain определяет набор событий, одним из которых является DomainUnload. Это событие генерируется тогда, когда домен приложения (не являющийся доменом, созданным по умолчанию) выгружается из содержащего этот домен процесса. Другим заслуживающим внимания событием является событие ProcessExit, которое генерируется при выгрузке из процесса домена, создаваемого по умолчанию (что, очевидно, влечет за собой завершение всего процесса). Так, если вы хотите программно выгрузить anotherAD из процесса AppDomainManipulator.exe и получить извещение о том, что соответствующий домен приложения закрыт, можете использовать следующую программную логику событий.
static void Main(string[] args) {
…
// Привязка к событию DomainUnload.
anotherAD.DomainUnload += new EventHandler(anotherAD_DomainUnload);
// Теперь выгрузка anotherAD.
AppDomain.Unload(anotherAD);
}
Обратите внимание на то, что событие DomainUnload работает в паре с делегатом System.EventHandler, поэтому формат anotherAD_DomainUnload() требует следующих аргументов.
public static void anotherAD_DomainUnload(object sender, EventArgs e) {
Console.WriteLine("***** Выгрузка anotherAD! *****n");
}
Если вы хотите получить извещение при выгрузке домена приложения, созданного по умолчанию, измените метод Main() так, чтобы обработать событие ProcessEvent, соответствующее домену приложения по умолчанию:
static void Main(string [] args) {
…
AppDomain defaultAD = AppDomain.CurrentDomain;
defaultAD.ProcessExit +=new EventHandler(defaultAD_ProcessExit);
}
и определите подходящий обработчик событий.
private static void defaultAD_ProcessExit (object sender, EventArgs e) {
Console.WriteLine("***** Выгрузка defaultAD! *****n");
}
Исходный код. Проект AppDomainManipulator размещен в подкаталоге, соответствующем главе 13.
Границы контекста объекта
Итак, вы могли убедиться, что домены приложения – это логические разделы в рамках процесса, предназначенные для загрузки компоновочных блоков .NET. Домен приложения, в свою очередь, можно делить дальше на контекстные области со своими границами. В сущности, контекст .NET обеспечивает домену приложения возможность создать "Отдельную комнату" для данного объекта.
Используя контекст, среда CLR может гарантировать, что объекты, которые выдвигают специальные требования в среде выполнении, будут обработаны надлежащим образам и в нужном порядке, поскольку для этого среда использует перехват вызовов, пересекающих границу контекста. Слой перехвата позволяет среде CLR корректировать текущие вызовы методов в соответствии с контекстно-зависимыми установками данного объекта. Например, если вы определите тип класса C#, требующий автоматической поддержки множества потоков (используя атрибут [Synchronization]), то среда CLR при его размещении создаст "синхронизированный контекст".
Точно так же, как процесс определяет создаваемый по умолчанию домен приложения, каждый домен приложения имеет создаваемый по умолчанию контекст. Этот создаваемый по умолчанию контекст (на который иногда ссылаются, как на контекст 0, поскольку он всегда оказывается первым контекстом, создаваемым в домене приложений) применяется для тех объектов .NET, которые не имеют никаких особых или уникальных контекстных требований. Вы вправе ожидать, что подавляющее большинство объектов .NET должно загружаться в контекст 0. Когда среда CLR определяет новый объект, имеющий специальные требования, создаются новые границы контекста в рамках объемлющего домена приложения. На рис. 13.9 показана схема взаимодействия процесса, доменов приложения и контекстов.
Рис. 13.9. Процессы, домены приложения и границы контекста
Контекстно-независимые и контекстно-связанные типы
Типы .NET которые не предъявляют никаких специальных контекстных требований, называются контекстно-независимыми объектами. Эти объекты доступны из любого места в рамках соответствующего домена приложения, без каких бы то ни было особых требований к среде выполнения. Построение контекстно-независимых объектов не требует больших усилий, поскольку ничего специального делать не приходится (в частности, не требуется наделять тип контекстными атрибутами или получать производные базового класса System.ContextBoundObject).
// Контекстно-независимый объект загружается в контекст 0.
public class SportsCar()
С другой стороны, объекты, которые требуют контекстного размещения, называются контекстно-связанными объектами, и они должны быть производными от базового класса System.ContextBoundObject. Этот базовый класс закрепляет тот факт, что соответствующий объект сможет правильно функционировать только в рамках контекста, в котором он был создан. С учетом роли контекста .NET должно быть ясно, что в случае, когда контекстно-связанный объект оказывается в несоответствующем контексте, в любой момент могут возникнуть проблемы.