다음을 통해 공유


AppDomain 클래스

응용 프로그램이 실행되는 격리된 환경인 응용 프로그램 도메인을 나타냅니다. 이 클래스는 상속될 수 없습니다.

네임스페이스: System
어셈블리: mscorlib(mscorlib.dll)

구문

‘선언
<ClassInterfaceAttribute(ClassInterfaceType.None)> _
<ComVisibleAttribute(True)> _
Public NotInheritable Class AppDomain
    Inherits MarshalByRefObject
    Implements _AppDomain, IEvidenceFactory
‘사용 방법
Dim instance As AppDomain
[ClassInterfaceAttribute(ClassInterfaceType.None)] 
[ComVisibleAttribute(true)] 
public sealed class AppDomain : MarshalByRefObject, _AppDomain, IEvidenceFactory
[ClassInterfaceAttribute(ClassInterfaceType::None)] 
[ComVisibleAttribute(true)] 
public ref class AppDomain sealed : public MarshalByRefObject, _AppDomain, IEvidenceFactory
/** @attribute ClassInterfaceAttribute(ClassInterfaceType.None) */ 
/** @attribute ComVisibleAttribute(true) */ 
public final class AppDomain extends MarshalByRefObject implements _AppDomain, IEvidenceFactory
ClassInterfaceAttribute(ClassInterfaceType.None) 
ComVisibleAttribute(true) 
public final class AppDomain extends MarshalByRefObject implements _AppDomain, IEvidenceFactory

설명

AppDomain 개체에 의해 표현되는 응용 프로그램 도메인은 관리 코드를 실행하기 위한 격리, 언로드 및 보안 경계를 제공합니다.

  • 응용 프로그램 도메인을 사용하여 프로세스를 중단시킬 수 있는 작업을 격리합니다. 작업을 실행하는 AppDomain의 상태가 불안정해질 경우 프로세스에 영향을 주지 않고 AppDomain을 언로드할 수 있습니다. 이 작업은 프로세스를 다시 시작하지 않고 오랫동안 실행해야 하는 경우 중요합니다. 또한 응용 프로그램 도메인을 사용하여 데이터를 공유하지 않아야 하는 작업을 격리할 수도 있습니다.

  • 기본 응용 프로그램 도메인에 로드된 어셈블리는 프로세스가 실행하는 동안 메모리에서 언로드할 수 없습니다. 그러나 보조 응용 프로그램 도메인을 열어서 어셈블리를 로드하고 실행하면 응용 프로그램 도메인이 언로드될 때 어셈블리도 언로드됩니다. 이 기술을 사용하면 가끔씩 큰 DLL을 사용하는 장기 실행 프로세스의 작업 집합을 최소화할 수 있습니다.

여러 응용 프로그램 도메인이 하나의 프로세스에서 실행될 수 있지만 응용 프로그램 도메인과 스레드 간에는 일대일 상관 관계가 없습니다. 여러 스레드가 하나의 응용 프로그램 도메인에 속할 수 있고 지정된 스레드는 하나의 응용 프로그램 도메인에 한정되지 않지만 지정된 시간에 스레드는 하나의 응용 프로그램 도메인에서 실행됩니다.

응용 프로그램 도메인은 CreateDomain 메서드를 사용하여 만들어집니다. AppDomain 인스턴스는 어셈블리(Assembly)를 로드 및 실행하는 데 사용됩니다. AppDomain이 더 이상 사용되지 않으면 언로드할 수 있습니다.

AppDomain 클래스는 어셈블리가 로드되거나, 응용 프로그램 도메인이 언로드되거나, 처리되지 않은 예외가 throw될 때 응용 프로그램이 응답할 수 있도록 하는 이벤트 집합을 구현합니다.

응용 프로그램 도메인의 사용에 대한 자세한 내용은 응용 프로그램 도메인을 참조하십시오.

이 클래스는 MarshalByRefObject, _AppDomainIEvidenceFactory 인터페이스를 구현합니다.

AppDomain 개체에 대해 원격 가능 래퍼를 만들지 마십시오. 원격 가능 래퍼를 만들면 해당 AppDomain에 대한 참조를 원격으로 게시하게 되어 CreateInstance와 같은 메서드를 원격 액세스에 노출하게 되므로 해당 AppDomain에 대한 코드 액세스 보안에 실제로 문제가 발생할 수 있습니다. 이렇게 되면 원격 AppDomain에 연결하는 악의적인 클라이언트가 AppDomain에서 자체적으로 액세스하는 모든 리소스에 액세스할 수도 있습니다. 따라서 MarshalByRefObject를 확장하거나 악의적인 클라이언트에서 보안 시스템을 무시할 목적으로 사용할 수 있는 메서드를 구현하는 형식에 대해서는 원격 가능 래퍼를 만들지 마십시오.

경고

AppDomainSetup.DisallowCodeDownload 속성의 기본값은 false입니다. 이 설정은 서비스에 안전하지 못합니다. 서비스에서 부분 신뢰 코드를 다운로드하는 것을 방지하려면 이 속성을 true로 설정합니다.

Windows Mobile for Pocket PC, Windows Mobile for Smartphone, Windows CE 플랫폼 참고: 여러 응용 프로그램 도메인에서 사용하도록 어셈블리를 도메인 중립 코드 영역으로 로드하는 것은 지원되지 않습니다.

항목 위치
방법: 응용 프로그램 도메인에 어셈블리 로드 .NET Framework: Programming Fundamentals
방법: 응용 프로그램 도메인 구성 .NET Framework: Programming Fundamentals
방법: 응용 프로그램 도메인 만들기 .NET Framework: Programming Fundamentals
방법: 응용 프로그램 도메인 언로드 .NET Framework: Programming Fundamentals
방법: 응용 프로그램 도메인 구성 .NET Framework: 프로그래밍 기본 사항
방법: 응용 프로그램 도메인에 어셈블리 로드 .NET Framework: 프로그래밍 기본 사항
방법: 응용 프로그램 도메인 만들기 .NET Framework: 프로그래밍 기본 사항
방법: 응용 프로그램 도메인 언로드 .NET Framework: 프로그래밍 기본 사항

예제

이 예제에서는 새 AppDomain을 만들고 이 새 AppDomain의 형식을 인스턴스화한 다음 해당 형식의 개체와 통신하는 방법을 보여 주고 개체가 가비지 수집되도록 AppDomain을 언로드하는 방법도 보여 줍니다.

Imports System
Imports System.Reflection
Imports System.Threading

Module Module1
    Sub Main()

        ' Get and display the friendly name of the default AppDomain.
        Dim callingDomainName As String = Thread.GetDomain().FriendlyName
        Console.WriteLine(callingDomainName)

        ' Get and display the full name of the EXE assembly.
        Dim exeAssembly As String = [Assembly].GetEntryAssembly().FullName
        Console.WriteLine(exeAssembly)

        ' Construct and initialize settings for a second AppDomain.
        Dim ads As New AppDomainSetup()
        ads.ApplicationBase = _
            "file:///" + System.Environment.CurrentDirectory
        ads.DisallowBindingRedirects = False
        ads.DisallowCodeDownload = True
        ads.ConfigurationFile = _
            AppDomain.CurrentDomain.SetupInformation.ConfigurationFile

        ' Create the second AppDomain.
        Dim ad2 As AppDomain = AppDomain.CreateDomain("AD #2", Nothing, ads)

        ' Create an instance of MarshalbyRefType in the second AppDomain. 
        ' A proxy to the object is returned.
        Dim mbrt As MarshalByRefType = CType( _
            ad2.CreateInstanceAndUnwrap(exeAssembly, _
                 GetType(MarshalByRefType).FullName), MarshalByRefType)

        ' Call a method on the object via the proxy, passing the default 
        ' AppDomain's friendly name in as a parameter.
        mbrt.SomeMethod(callingDomainName)

        ' Unload the second AppDomain. This deletes its object and 
        ' invalidates the proxy object.
        AppDomain.Unload(ad2)
        Try
            ' Call the method again. Note that this time it fails because 
            ' the second AppDomain was unloaded.
            mbrt.SomeMethod(callingDomainName)
            Console.WriteLine("Sucessful call.")
        Catch e As AppDomainUnloadedException
            Console.WriteLine("Failed call; this is expected.")
        End Try

    End Sub
End Module

' Because this class is derived from MarshalByRefObject, a proxy 
' to a MarshalByRefType object can be returned across an AppDomain 
' boundary.
Public Class MarshalByRefType
    Inherits MarshalByRefObject

    '  Call this method via a proxy.
    Public Sub SomeMethod(ByVal callingDomainName As String)

        ' Get this AppDomain's settings and display some of them.
        Dim ads As AppDomainSetup = AppDomain.CurrentDomain.SetupInformation
        Console.WriteLine("AppName={0}, AppBase={1}, ConfigFile={2}", _
            ads.ApplicationName, ads.ApplicationBase, ads.ConfigurationFile)

        ' Display the name of the calling AppDomain and the name 
        ' of the second domain.
        ' NOTE: The application's thread has transitioned between 
        ' AppDomains.
        Console.WriteLine("Calling from '{0}' to '{1}'.", _
            callingDomainName, Thread.GetDomain().FriendlyName)
    End Sub
End Class

'This code produces output similar to the following:
' 
' AppDomainX.exe
' AppDomainX, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
' AppName=, AppBase=C:\AppDomain\bin, ConfigFile=C:\AppDomain\bin\AppDomainX.exe.config
' Calling from 'AppDomainX.exe' to 'AD #2'.
' Failed call; this is expected.
using System;
using System.Reflection;
using System.Threading;

class Module1
{
    public static void Main()
    {
        // Get and display the friendly name of the default AppDomain.
        string callingDomainName = Thread.GetDomain().FriendlyName;
        Console.WriteLine(callingDomainName);

        // Get and display the full name of the EXE assembly.
        string exeAssembly = Assembly.GetEntryAssembly().FullName;
        Console.WriteLine(exeAssembly);

        // Construct and initialize settings for a second AppDomain.
        AppDomainSetup ads = new AppDomainSetup();
        ads.ApplicationBase = 
            "file:///" + System.Environment.CurrentDirectory;
        ads.DisallowBindingRedirects = false;
        ads.DisallowCodeDownload = true;
        ads.ConfigurationFile = 
            AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;

        // Create the second AppDomain.
        AppDomain ad2 = AppDomain.CreateDomain("AD #2", null, ads);

        // Create an instance of MarshalbyRefType in the second AppDomain. 
        // A proxy to the object is returned.
        MarshalByRefType mbrt = 
            (MarshalByRefType) ad2.CreateInstanceAndUnwrap(
                exeAssembly, 
                typeof(MarshalByRefType).FullName
            );

        // Call a method on the object via the proxy, passing the 
        // default AppDomain's friendly name in as a parameter.
        mbrt.SomeMethod(callingDomainName);

        // Unload the second AppDomain. This deletes its object and 
        // invalidates the proxy object.
        AppDomain.Unload(ad2);
        try
        {
            // Call the method again. Note that this time it fails 
            // because the second AppDomain was unloaded.
            mbrt.SomeMethod(callingDomainName);
            Console.WriteLine("Sucessful call.");
        }
        catch(AppDomainUnloadedException)
        {
            Console.WriteLine("Failed call; this is expected.");
        }
    }
}

// Because this class is derived from MarshalByRefObject, a proxy 
// to a MarshalByRefType object can be returned across an AppDomain 
// boundary.
public class MarshalByRefType : MarshalByRefObject
{
    //  Call this method via a proxy.
    public void SomeMethod(string callingDomainName)
    {
        // Get this AppDomain's settings and display some of them.
        AppDomainSetup ads = AppDomain.CurrentDomain.SetupInformation;
        Console.WriteLine("AppName={0}, AppBase={1}, ConfigFile={2}", 
            ads.ApplicationName, 
            ads.ApplicationBase, 
            ads.ConfigurationFile
        );

        // Display the name of the calling AppDomain and the name 
        // of the second domain.
        // NOTE: The application's thread has transitioned between 
        // AppDomains.
        Console.WriteLine("Calling from '{0}' to '{1}'.", 
            callingDomainName, 
            Thread.GetDomain().FriendlyName
        );
    }
}

/* This code produces output similar to the following: 

AppDomainX.exe
AppDomainX, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
AppName=, AppBase=C:\AppDomain\bin, ConfigFile=C:\AppDomain\bin\AppDomainX.exe.config
Calling from 'AppDomainX.exe' to 'AD #2'.
Failed call; this is expected.
 */
using namespace System;
using namespace System::Reflection;
using namespace System::Threading;
using namespace System::Security::Policy;

// Because this class is derived from MarshalByRefObject, a proxy 
// to a MarshalByRefType object can be returned across an AppDomain 
// boundary.
ref class MarshalByRefType : MarshalByRefObject
{
public:
    //  Call this method via a proxy.
    void SomeMethod(String^ callingDomainName)
    {
        // Get this AppDomain's settings and display some of them.
        AppDomainSetup^ ads = AppDomain::CurrentDomain->SetupInformation;
        Console::WriteLine("AppName={0}, AppBase={1}, ConfigFile={2}", 
            ads->ApplicationName, 
            ads->ApplicationBase, 
            ads->ConfigurationFile
        );

        // Display the name of the calling AppDomain and the name 
        // of the second domain.
        // NOTE: The application's thread has transitioned between 
        // AppDomains.
        Console::WriteLine("Calling from '{0}' to '{1}'.", 
            callingDomainName, 
            Thread::GetDomain()->FriendlyName
        );
    };
};

void main()
{
    // Get and display the friendly name of the default AppDomain.
    String^ callingDomainName = Thread::GetDomain()->FriendlyName;
    Console::WriteLine(callingDomainName);

    // Get and display the full name of the EXE assembly.
    String^ exeAssembly = Assembly::GetEntryAssembly()->FullName;
    Console::WriteLine(exeAssembly);

    // Construct and initialize settings for a second AppDomain.
    AppDomainSetup^ ads = gcnew AppDomainSetup();
    ads->ApplicationBase = 
        "file:///" + System::Environment::CurrentDirectory;
    ads->DisallowBindingRedirects = false;
    ads->DisallowCodeDownload = true;
    ads->ConfigurationFile = 
        AppDomain::CurrentDomain->SetupInformation->ConfigurationFile;

    // Create the second AppDomain.
    AppDomain^ ad2 = AppDomain::CreateDomain("AD #2", 
        AppDomain::CurrentDomain->Evidence, ads);

    // Create an instance of MarshalbyRefType in the second AppDomain. 
    // A proxy to the object is returned.
    MarshalByRefType^ mbrt = 
        (MarshalByRefType^) ad2->CreateInstanceAndUnwrap(
            exeAssembly, 
            MarshalByRefType::typeid->FullName
        );

    // Call a method on the object via the proxy, passing the 
    // default AppDomain's friendly name in as a parameter.
    mbrt->SomeMethod(callingDomainName);

    // Unload the second AppDomain. This deletes its object and 
    // invalidates the proxy object.
    AppDomain::Unload(ad2);
    try
    {
        // Call the method again. Note that this time it fails 
        // because the second AppDomain was unloaded.
        mbrt->SomeMethod(callingDomainName);
        Console::WriteLine("Sucessful call.");
    }
    catch(AppDomainUnloadedException^)
    {
        Console::WriteLine("Failed call; this is expected.");
    }
}

/* This code produces output similar to the following: 

AppDomainX.exe
AppDomainX, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
AppName=, AppBase=C:\AppDomain\bin, ConfigFile=C:\AppDomain\bin\AppDomainX.exe.config
Calling from 'AppDomainX.exe' to 'AD #2'.
Failed call; this is expected.
 */

상속 계층 구조

System.Object
   System.MarshalByRefObject
    System.AppDomain

스레드로부터의 안전성

이 형식의 모든 public static(Visual Basic의 경우 Shared) 멤버는 스레드로부터 안전합니다. 인터페이스 멤버는 스레드로부터 안전하지 않습니다.

플랫폼

Windows 98, Windows 2000 SP4, Windows CE, Windows Millennium Edition, Windows Mobile for Pocket PC, Windows Mobile for Smartphone, Windows Server 2003, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP SP2, Windows XP Starter Edition

.NET Framework에서 모든 플래폼의 모든 버전을 지원하지는 않습니다. 지원되는 버전의 목록은 시스템 요구 사항을 참조하십시오.

버전 정보

.NET Framework

2.0, 1.1, 1.0에서 지원

.NET Compact Framework

2.0, 1.0에서 지원

참고 항목

참조

AppDomain 멤버
System 네임스페이스