Домены приложенийApplication domains

Операционные системы и среды выполнения обычно содержат определенные средства изоляции приложений друг от друга.Operating systems and runtime environments typically provide some form of isolation between applications. Например, в ОС Windows для изоляции приложений используются процессы.For example, Windows uses processes to isolate applications. Эта изоляция необходима, чтобы гарантировать, что код, выполняемый одним приложением, не сможет нарушить работу других, не связанных с ним приложений.This isolation is necessary to ensure that code running in one application cannot adversely affect other, unrelated applications.

Домены приложений образуют изолированную область для безопасности, надежности, управления версиями и выгрузки сборок.Application domains provide an isolation boundary for security, reliability, and versioning, and for unloading assemblies. Домены приложений обычно создаются базовыми средами выполнения, которые отвечают за начальную загрузку среды CLR перед запуском приложения.Application domains are typically created by runtime hosts, which are responsible for bootstrapping the common language runtime before an application is run.

Преимущества изоляции приложенийThe benefits of isolating applications

Исторически сложилось так, что для разделения приложений, выполняющихся на одном компьютере, используются границы процессов.Historically, process boundaries have been used to isolate applications running on the same computer. Каждое приложение загружается в отдельный процесс, который отделяет его от других приложений, выполняющихся на том же компьютере.Each application is loaded into a separate process, which isolates the application from other applications running on the same computer.

Приложения оказываются изолированными друг от друга, поскольку адреса в памяти привязаны к процессам; бессмысленно использовать в процессе указатель, передаваемый ему из другого процесса.The applications are isolated because memory addresses are process-relative; a memory pointer passed from one process to another cannot be used in any meaningful way in the target process. Кроме того, прямые вызовы между процессами невозможны.In addition, you cannot make direct calls between two processes. Вместо этого необходимо использовать прокси, которые обеспечивают уровень косвенности.Instead, you must use proxies, which provide a level of indirection.

Перед запуском управляемый код должен пройти процесс проверки (если администратор не даст разрешение пропустить проверку).Managed code must be passed through a verification process before it can be run (unless the administrator has granted permission to skip the verification). В процессе проверки определяется, может ли код предпринимать попытки обращения к неверным адресам памяти или осуществлять другие действия, способные привести к нарушению правильной работы процесса, в котором выполняется этот код.The verification process determines whether the code can attempt to access invalid memory addresses or perform some other action that could cause the process in which it is running to fail to operate properly. Код, прошедший проверку, называется типобезопасным.Code that passes the verification test is said to be type-safe. Возможность проверки кода на безопасность типа позволяет среде CLR обеспечивать такой же высокий уровень изоляции процессов друг от друга, как и при использовании границ процессов, но со значительно более низкими затратами по производительности.The ability to verify code as type-safe enables the common language runtime to provide as great a level of isolation as the process boundary, at a much lower performance cost.

Домены приложений предоставляют среде CLR более безопасные и гибкие блоки, которые могут использоваться для разделения отдельных приложений.Application domains provide a more secure and versatile unit of processing that the common language runtime can use to provide isolation between applications. В одном процессе можно запустить несколько доменов приложений с таким же уровнем изоляции, какой обеспечивают отдельные процессы, но без дополнительных издержек на межпроцессные вызовы или переключение между процессами.You can run several application domains in a single process with the same level of isolation that would exist in separate processes, but without incurring the additional overhead of making cross-process calls or switching between processes. Возможность выполнения нескольких приложений в одном процессе значительно повышает масштабируемость серверов.The ability to run multiple applications within a single process dramatically increases server scalability.

Изоляция приложений также играет важную роль в обеспечении безопасности.Isolating applications is also important for application security. Так, например, можно запустить элементы управления нескольких веб-приложений в одном процессе браузера так, что эти элементы управления не смогут получить доступ к данным и ресурсам друг друга.For example, you can run controls from several Web applications in a single browser process in such a way that the controls cannot access each other's data and resources.

Изоляция приложений при помощи доменов приложений имеет следующие преимущества.The isolation provided by application domains has the following benefits:

  • Сбои в одном из приложений не затронут прочие приложения.Faults in one application cannot affect other applications. Поскольку типобезопасный код не может вызывать сбои в памяти, использование доменов приложений гарантирует, что код, выполняющийся в одном домене, не окажет воздействия на другие приложения процесса.Because type-safe code cannot cause memory faults, using application domains ensures that code running in one domain cannot affect other applications in the process.

  • Можно прекратить выполнение отдельных приложений, не останавливая процесс целиком.Individual applications can be stopped without stopping the entire process. Использование доменов приложений позволяет выгружать код, используемый отдельным приложением.Using application domains enables you to unload the code running in a single application.

    Примечание

    Невозможно выгружать отдельные сборки или типы.You cannot unload individual assemblies or types. Выгрузить можно только домен целиком.Only a complete domain can be unloaded.

  • Код, используемый одним приложением, не может иметь непосредственного доступа к коду или ресурсам другого приложения.Code running in one application cannot directly access code or resources from another application. В среде CLR эта изоляция реализована за счет запрета прямых вызовов между объектами в различных доменах приложений.The common language runtime enforces this isolation by preventing direct calls between objects in different application domains. Объекты, передаваемые от домена к домену, копируются или взаимодействуют через прокси.Objects that pass between domains are either copied or accessed by proxy. Если объект копируется, вызов этого объекта является локальным.If the object is copied, the call to the object is local. То есть вызывающий и вызываемый объекты находятся в одном домене приложения.That is, both the caller and the object being referenced are in the same application domain. Если доступ к объекту осуществляется через прокси, осуществляется удаленный вызов объекта.If the object is accessed through a proxy, the call to the object is remote. В этом случае вызывающий и вызываемый объекты находятся в разных доменах приложений.In this case, the caller and the object being referenced are in different application domains. При междоменных вызовах используется та же инфраструктура удаленных вызовов, что и при вызовах между двумя разными процессами или двумя разными компьютерами.Cross-domain calls use the same remote call infrastructure as calls between two processes or between two machines. Для правильной JIT-компиляции вызова метода метаданные используемого объекта должны быть доступны для обоих доменов приложений.As such, the metadata for the object being referenced must be available to both application domains to allow the method call to be JIT-compiled properly. Если вызывающий домен не имеет доступа к метаданным для вызванного объекта, компиляция может завершиться ошибкой с исключением типа FileNotFoundException.If the calling domain does not have access to the metadata for the object being called, the compilation might fail with an exception of type FileNotFoundException. Для получения дополнительной информации см. Remote Objects.For more information, see Remote Objects. Механизм определения способов междоменного доступа для объекта зависит от объекта.The mechanism for determining how objects can be accessed across domains is determined by the object. Дополнительные сведения можно найти по адресу: System.MarshalByRefObject.For more information, see System.MarshalByRefObject.

  • Поведение кода определяется границами приложения, в котором он выполняется.The behavior of code is scoped by the application in which it runs. Другими словами, домен приложения предоставляет параметры конфигурации, такие как политики управления версиями приложения, местоположение удаленных сборок, к которым выполняется обращение, и сведения о том, где следует искать локальные сборки, загруженные в домен.In other words, the application domain provides configuration settings such as application version policies, the location of any remote assemblies it accesses, and information about where to locate assemblies that are loaded into the domain.

  • Разрешения, предоставленные коду, могут управляться доменом приложения, в котором выполняется этот код.Permissions granted to code can be controlled by the application domain in which the code is running.

Домены приложений и сборкиApplication domains and assemblies

В этом разделе описывается связью между доменами приложений и сборками.This section describes the relationship between application domains and assemblies. Чтобы выполнить код сборки, ее необходимо загрузить в домен приложения.You must load an assembly into an application domain before you can execute the code it contains. Как правило, для запуска приложения в домен приложения необходимо загрузить несколько сборок.Running a typical application causes several assemblies to be loaded into an application domain.

Способ загрузки определяет, можно ли использовать JIT-скомпилированный код сборки в нескольких доменах приложений в процессе и можно ли выгружать сборку из процесса.The way an assembly is loaded determines whether its just-in-time (JIT) compiled code can be shared by multiple application domains in the process, and whether the assembly can be unloaded from the process.

  • Если сборка загружается как нейтральная к домену, то все домены приложений с одним набором разрешений безопасности могут совместно использовать JIT-скомпилированный код, что снижает требуемый для приложения объем памяти.If an assembly is loaded domain-neutral, all application domains that share the same security grant set can share the same JIT-compiled code, which reduces the memory required by the application. Однако сборку нельзя выгружать из процесса.However, the assembly can never be unloaded from the process.

  • Если сборка не загружается как нейтральная к домену, она должна быть JIT-скомпилирована в каждом домене приложения, в который она загружается.If an assembly is not loaded domain-neutral, it must be JIT-compiled in every application domain in which it is loaded. Однако сборку можно выгрузить из процесса, выгрузив все домены приложений, в которые она загружается.However, the assembly can be unloaded from the process by unloading all the application domains in which it is loaded.

Следует ли загружать сборки как нейтральные к домену, определяется в хост-приложении среды выполнения при загрузке среды выполнения в процесс.The runtime host determines whether to load assemblies as domain-neutral when it loads the runtime into a process. Для управляемых приложений примените атрибут LoaderOptimizationAttribute к методу точки входа процесса и укажите значение из связанного перечисления LoaderOptimization.For managed applications, apply the LoaderOptimizationAttribute attribute to the entry-point method for the process, and specify a value from the associated LoaderOptimization enumeration. Для неуправляемых приложений, в которых размещается среда CLR, при вызове функции CorBindToRuntimeEx задайте соответствующий флаг.For unmanaged applications that host the common language runtime, specify the appropriate flag when you call the CorBindToRuntimeEx Function method.

Существует три варианта загрузки нейтральных к домену сборок.There are three options for loading domain-neutral assemblies:

  • LoaderOptimization.SingleDomain не загружает сборки как нейтральные к домену, за исключением Mscorlib, которая всегда загружается как нейтральная к домену.LoaderOptimization.SingleDomain loads no assemblies as domain-neutral, except Mscorlib, which is always loaded domain-neutral. Этот вариант называется однодоменным, поскольку обычно он используется, когда в хост-приложении запускается только одно приложение в процессе.This setting is called single domain because it is commonly used when the host is running only a single application in the process.

  • LoaderOptimization.MultiDomain загружает все сборки как нейтральные к домену.LoaderOptimization.MultiDomain loads all assemblies as domain-neutral. Этот вариант используется при наличии нескольких доменов приложений, в каждом из которых выполняется одинаковый код.Use this setting when there are multiple application domains in the process, all of which run the same code.

  • LoaderOptimization.MultiDomainHost загружает сборки со строгими именами как нейтральные к домену, если они и все их зависимости установлены в глобальном кэше сборок.LoaderOptimization.MultiDomainHost loads strong-named assemblies as domain-neutral, if they and all their dependencies have been installed in the global assembly cache. Другие сборки загружаются и JIT-компилируются отдельно для каждого домена приложения, в котором они загружаются, поэтому могут выгружаться из процесса.Other assemblies are loaded and JIT-compiled separately for each application domain in which they are loaded, and thus can be unloaded from the process. Этот вариант используется при работе нескольких приложений в одном процессе или при наличии набора сборок, которые являются общими для нескольких доменов приложений, и сборок, которые должны выгружаться из процесса.Use this setting when running more than one application in the same process, or if you have a mixture of assemblies that are shared by many application domains and assemblies that need to be unloaded from the process.

JIT-скомпилированный код нельзя сделать общим для сборок, загруженных в контекст загрузки с помощью метода LoadFrom класса Assembly или загруженных из образов с помощью перегрузок метода Load, задающего байтовые массивы.JIT-compiled code cannot be shared for assemblies loaded into the load-from context, using the LoadFrom method of the Assembly class, or loaded from images using overloads of the Load method that specify byte arrays.

Сборки, которые были скомпилированы в машинный код с помощью Ngen.exe (средства для создания машинных образов), могут совместно использоваться доменами приложений, если они загружены как нейтральные к домену при первой загрузке в процесс.Assemblies that have been compiled to native code by using the Ngen.exe (Native Image Generator) can be shared between application domains, if they are loaded domain-neutral the first time they are loaded into a process.

JIT-скомпилированный код для сборки, содержащей точку входа приложения, может быть общим, только если все его зависимости могут использоваться совместно.JIT-compiled code for the assembly that contains the application entry point is shared only if all its dependencies can be shared.

Сборка, нейтральная к домену, может JIT-компилироваться более одного раза.A domain-neutral assembly can be JIT-compiled more than once. Например, когда наборы разрешений безопасности двух доменов приложений отличаются, они не могут совместно использовать один и тот же JIT-скомпилированный код.For example, when the security grant sets of two application domains are different, they cannot share the same JIT-compiled code. Однако каждая копия JIT-скомпилированной сборки может использоваться совместно с другими доменами приложений, имеющими такой же набор разрешений.However, each copy of the JIT-compiled assembly can be shared with other application domains that have the same grant set.

При принятии решения о том, следует ли загружать сборки как нейтральные, осуществляется компромисс между сокращением расхода памяти и производительностью.When you decide whether to load assemblies as domain-neutral, you must make a tradeoff between reducing memory use and other performance factors.

  • Доступ к статическим данным и методам для нейтральных к домену сборок осуществляется медленнее из-за необходимости изоляции сборок.Access to static data and methods is slower for domain-neutral assemblies because of the need to isolate assemblies. Каждый домен приложения, обращающийся к сборке, должен обладать собственной копией статических данных, чтобы избежать ссылок на объекты в статических полях, пересекающих границы домена.Each application domain that accesses the assembly must have a separate copy of the static data, to prevent references to objects in static fields from crossing domain boundaries. В результате среда выполнения содержит дополнительные правила для перенаправления вызывающего объекта к соответствующей копии статических данных или метода.As a result, the runtime contains additional logic to direct a caller to the appropriate copy of the static data or method. Эти дополнительные правила замедляют вызов.This extra logic slows down the call.

  • При загрузке сборки как нейтральной к домену необходимо найти и загрузить все зависимости сборки, поскольку зависимость, которую нельзя загрузить как нейтральную, не позволяет загрузить сборку как нейтральную.All the dependencies of an assembly must be located and loaded when the assembly is loaded domain-neutral, because a dependency that cannot be loaded domain-neutral prevents the assembly from being loaded domain-neutral.

Домены приложений и потокиApplication domains and threads

Домен приложения формирует изолированную область для безопасности, управления версиями, надежности и выгрузки управляемого кода.An application domain forms an isolation boundary for security, versioning, reliability, and unloading of managed code. Поток представляет собой конструкцию операционной системы, используемую в среде CLR для выполнения кода.A thread is the operating system construct used by the common language runtime to execute code. Во время выполнения весь управляемый код загружается в домен приложения и выполняется в одном или нескольких управляемых потоках.At run time, all managed code is loaded into an application domain and is run by one or more managed threads.

Однозначного соответствия между потоками и доменами приложений не существует.There is not a one-to-one correlation between application domains and threads. В одном домене приложения могут одновременно выполняться несколько потоков, при этом конкретный поток не ограничен одним доменом приложения.Several threads can execute in a single application domain at any given time, and a particular thread is not confined to a single application domain. Таким образом, потоки могут использоваться в разных доменах приложений. Новый поток для каждого домена приложения не создается.That is, threads are free to cross application domain boundaries; a new thread is not created for each application domain.

В любой момент времени каждый поток выполняется в каком-либо домене приложения.At any given time, every thread executes in an application domain. В домене приложения может выполняться один или несколько потоков или не выполняться ни одного потока.Zero, one, or multiple threads might be executing in any given application domain. Среда выполнения отслеживает соответствие потоков и доменов приложений, в которых они выполняются.The runtime keeps track of which threads are running in which application domains. В любой момент времени можно найти домен, в котором выполняется поток, вызвав метод Thread.GetDomain.You can locate the domain in which a thread is executing at any time by calling the Thread.GetDomain method.

Домены приложений и язык и региональные параметрыApplication domains and cultures

Язык и региональные параметры, представляемые объектом CultureInfo, связаны с потоками.Culture, which is represented by a CultureInfo object, is associated with threads. Чтобы получить язык и региональные параметры, связанные с выполняющимся в данный момент потоком, используйте свойство CultureInfo.CurrentCulture, а чтобы получить или задать язык и региональные параметры, связанные с выполняющимся в данный момент потоком, используйте свойство Thread.CurrentCulture.You can get the culture that is associated with the currently executing thread by using the CultureInfo.CurrentCulture property, and you can get or set the culture that is associated with the currently executing thread by using the Thread.CurrentCulture property. Если связанные с потоком язык и региональные параметры явно заданы с помощью свойства Thread.CurrentCulture, они будут связаны с этим потоком и за пределами домена приложения.If the culture that is associated with a thread has been explicitly set by using the Thread.CurrentCulture property, it continues to be associated with that thread when the thread crosses application domain boundaries. В противном случае связанные с потоком язык и региональные параметры в любой момент времени определяются значением свойства CultureInfo.DefaultThreadCurrentCulture в домене приложения, где выполняется поток:Otherwise, the culture that is associated with the thread at any given time is determined by the value of the CultureInfo.DefaultThreadCurrentCulture property in the application domain in which the thread is executing:

  • Если значение этого свойства — не null, возвращаемые им язык и региональные параметры связаны с потоком (и следовательно возвращаются свойствами Thread.CurrentCulture и CultureInfo.CurrentCulture).If the value of the property is not null, the culture that is returned by the property is associated with the thread (and therefore returned by the Thread.CurrentCulture and CultureInfo.CurrentCulture properties).

  • Если значение этого свойства – null, с потоком связываются текущие настройки языка и региональных параметров системы.If the value of the property is null, the current system culture is associated with the thread.

Программирование с использованием доменов приложенийProgramming with application domains

Домены приложений обычно создаются и управляются программно, хост-приложениями среды выполнения.Application domains are usually created and manipulated programmatically by runtime hosts. Однако иногда работать с доменами приложений требуется самим приложениям.However, sometimes an application program might also want to work with application domains. Например, приложение может загружать компонент в домен, чтобы иметь возможность выгрузить домен (и компонент) без необходимости останавливать все приложение.For example, an application program could load an application component into a domain to be able to unload the domain (and the component) without having to stop the entire application.

AppDomain — это программный интерфейс для доменов приложений.The AppDomain is the programmatic interface to application domains. Этот класс содержит методы для создания и выгрузки доменов, для создания экземпляров типов в доменах и для подписки на различные уведомления, такие как выгрузка домена приложения.This class includes methods to create and unload domains, to create instances of types in domains, and to register for various notifications such as application domain unloading. В следующей таблице перечислены часто используемые методы AppDomain.The following table lists commonly used AppDomain methods.

Метод AppDomainAppDomain Method ОПИСАНИЕDescription
CreateDomain Создает новый домен приложения.Creates a new application domain. Рекомендуется использовать перегрузку этого метода, в которой определяется объект AppDomainSetup.It is recommended that you use an overload of this method that specifies an AppDomainSetup object. Это предпочтительный способ установки свойств нового домена, таких как база приложения или корневой каталог приложения, расположение файла конфигурации домена и путь поиска, используемый средой CLR для загрузки сборок в домен.This is the preferred way to set the properties of a new domain, such as the application base, or root directory for the application; the location of the configuration file for the domain; and the search path that the common language runtime is to use to load assemblies into the domain.
ExecuteAssembly и ExecuteAssemblyByNameExecuteAssembly and ExecuteAssemblyByName Выполняет сборку в домене приложения.Executes an assembly in the application domain. Это метод экземпляра, поэтому его можно использовать для выполнения кода в другом домене приложения, на который имеется ссылка.This is an instance method, so it can be used to execute code in another application domain to which you have a reference.
CreateInstanceAndUnwrap Создает экземпляр указанного типа в домене приложения и возвращает прокси.Creates an instance of a specified type in the application domain, and returns a proxy. Этот метод служит для избежания загрузки сборки, содержащей созданный тип, в вызывающую сборку.Use this method to avoid loading the assembly containing the created type into the calling assembly.
Unload Корректно завершает работу домена.Performs a graceful shutdown of the domain. Домен приложения не выгружается до тех пор, пока все запущенные в домене потоки не будут остановлены или исключены из домена.The application domain is not unloaded until all threads running in the domain have either stopped or are no longer in the domain.

Примечание

Среда CLR не поддерживает сериализацию глобальных методов, поэтому для выполнения глобальных методов в других доменах приложений использовать делегаты нельзя.The common language runtime does not support serialization of global methods, so delegates cannot be used to execute global methods in other application domains.

Неуправляемые интерфейсы, описанные в спецификации Hosting Interfaces Specification для среды CLR, также предоставляют доступ к доменам приложений.The unmanaged interfaces described in the common language runtime Hosting Interfaces Specification also provide access to application domains. Хост-приложения среды выполнения могут использовать интерфейсы из неуправляемого кода для создания доменов приложений внутри процесса и для получения доступа к ним.Runtime hosts can use interfaces from unmanaged code to create and gain access to the application domains within a process.

Переменная среды COMPLUS_LoaderOptimizationThe COMPLUS_LoaderOptimization environment variable

Переменная среды, которая задает политику оптимизации загрузчика по умолчанию для исполняемого приложения.An environment variable that sets the default loader optimization policy of an executable application.

СинтаксисSyntax

COMPLUS_LoaderOptimization = 1  

ПримечанияRemarks

Стандартное приложение загружает в домен приложения несколько сборок. После этого можно выполнить содержащийся в них код.A typical application loads several assemblies into an application domain before the code they contain can be executed.

Способ загрузки определяет, может ли JIT-скомпилированный код сборки использоваться несколькими доменами приложения в одном процессе.The way the assembly is loaded determines whether its just-in-time (JIT) compiled code can be shared by multiple application domains in the process.

  • Если сборка загружается как независимая от домена, то все домены приложения с одним набором разрешений безопасности могут использовать один JIT-скомпилированный код.If an assembly is loaded domain-neutral, all application domains that share the same security grant set can share the same JIT-compiled code. В этом случае приложение использует меньше памяти.This reduces the memory required by the application.

  • Если сборка загружается как зависимая от домена, ее необходимо JIT-компилировать во всех соответствующих доменах приложения, при этом в каждом случае загрузчик должен использовать разные внутренние ресурсы.If an assembly is not loaded domain-neutral, it must be JIT-compiled in every application domain in which it is loaded and the loader must not share internal resources across application domains.

Если значение флага среды COMPLUS_LoaderOptimization — 1, то хост-приложение среды выполнения использует способ загрузки SingleDomain.When set to 1, the COMPLUS_LoaderOptimization environment flag forces the runtime host to load all assemblies in non-domain-neutral way known as SingleDomain. Он принудительно загружает все сборки как зависимые от домена, за исключением сборки Mscorlib, которая всегда загружается как независимая.SingleDomain loads no assemblies as domain-neutral, except Mscorlib, which is always loaded domain-neutral. Этот вариант называется однодоменным, поскольку обычно он используется, когда в хост-приложении запускается только одно приложение в процессе.This setting is called single domain because it is commonly used when the host is running only a single application in the process.

Внимание!

Флаг среды COMPLUS_LoaderOptimization предназначен для сценариев диагностики и тестирования.The COMPLUS_LoaderOptimization environment flag was designed to be used in diagnostic and test scenarios. Когда он включен, работа может существенно замедляться, а использование памяти — увеличиваться.Having the flag turned on can cause severe slow-down and increase in memory usage.

Примеры кодаCode example

Чтобы все сборки для службы IISADMIN загружались как зависимые от домена, добавьте код COMPLUS_LoaderOptimization=1 в многострочный параметр среды в разделе HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\IISADMIN.To force all assemblies not to be loaded as domain-neutral for the IISADMIN service can be achieved by appending COMPLUS_LoaderOptimization=1 to the Environment’s Multi-String Value in the HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\IISADMIN key.

Key = HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\IISADMIN  
Name = Environment  
Type = REG_MULTI_SZ  
Value (to append) = COMPLUS_LoaderOptimization=1  

См. такжеSee also