AppDomain 및 Assembly의 동적 로드 및 언로드 코드에 대한 자세한 설명

黄舟
풀어 주다: 2017-03-15 11:02:12
원래의
3643명이 탐색했습니다.

문제를 명확하게 설명하기 위해 먼저 예를 살펴보겠습니다. 이 예에서는 WinForm에 버튼이 있습니다. 사용자가 이 버튼을 클릭하면 기존 어셈블리가 로드되고 인터페이스의 Label 컨트롤이 이 어셈블리의 전체 이름은 에 표시됩니다. Reflection에 조금 익숙한 친구들은 이것이 매우 간단한 일이라는 것을 알고 있습니다. Assembly.LoadFile 메서드를 사용하여 Assembly를 가져온 다음 FullName속성을 사용하면 됩니다. 아래 코드는 다음과 같습니다.

private void button1_Click(object sender, EventArgs e)  
{  
    Assembly assembly = Assembly.LoadFile(@"C:\testlib.dll");  
    label1.Text = assembly.FullName;  
}
로그인 후 복사



물론, 프로그램이 정상적으로 실행되지만 컴파일 시간이나 런타임 오류가 발견되지 않습니다. 그러나 이 프로그램을 종료하지 않고 호출된 testlib.dll을 컴파일하면 Visual Studio가 컴파일을 완료할 수 없으며 해당 파일이 다른 사용자에서 사용 중이라는 메시지가 표시됩니다. 프로세스.

사실 우리 프로그램은 이 testlib.dll과 밀접한 관련이 없습니다. 우리 프로그램은 단지 testlib.dll의 기본 정보만 표시할 뿐입니다. testlib.dll이 공유 라이브러리인 경우 리소스 독점 문제는 다른 프로그램의 정상적인 작동에 영향을 미칩니다.

Assembly에는 Unload 기능이 없지만 AppDomain을 사용하면 이 문제를 해결할 수 있습니다. 기본 아이디어는 새 AppDomain을 만들고, 이 새 AppDomain에 어셈블리를 로드하고, 그 안에 있는 메서드를 호출한 다음, 얻은 결과를 반환하는 것입니다. 모든 작업을 완료한 후 AppDomain.Unload 메서드를 호출하여 새로 생성된 AppDomain을 제거합니다. 그러면 어셈블리도 제거됩니다. 참고: 로드된 어셈블리를 현재 애플리케이션 도메인(AppDomain)으로 직접 반환할 수 없습니다.

먼저 RemoteLoader를 만듭니다. 이 RemoteLoader는 새로 생성된 AppDomain에 어셈블리를 로드하고 외부 세계에서 어셈블리의 FullName을 얻을 수 있도록 속성을 외부에 게시하는 데 사용됩니다. RemoteLoader는 MarshalByRefObject에서 상속 해야 합니다. 코드는 다음과 같습니다.

public class RemoteLoader : MarshalByRefObject  
{  
    private Assembly assembly;  
    public void LoadAssembly(string fullName)  
    {  
        assembly = Assembly.LoadFrom(fullName);  
    }  
    public string FullName  
    {  
        get { return assembly.FullName; }  
    }  
}
로그인 후 복사



두 번째로 Loc을 생성합니다모두로더. LocalLoader의 기능은 새 AppDomain을 만든 다음 이 새 AppDomain에서 RemoteLoader를 호출하여 어셈블리를 만들고 RemoteLoader를 통해 어셈블리 관련 정보를 얻는 것입니다. 이때 호출된 어셈블리는 새로운 AppDomain에 자연스럽게 로딩됩니다. 마지막으로 LocalLoader는 AppDomain 제거라는 새로운 방법도 제공해야 합니다. 코드는 다음과 같습니다.

public class LocalLoader  
{  
    private AppDomain appDomain;  
    private RemoteLoader remoteLoader;  
    public LocalLoader()  
    {  
        AppDomainSetup setup = new AppDomainSetup();  
        setup.ApplicationName = "Test";  
        setup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;  
        setup.PrivateBinPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "private");  
        setup.CachePath = setup.ApplicationBase;  
        setup.ShadowCopyFiles = "true";  
        setup.ShadowCopyDirectories = setup.ApplicationBase;  
        appDomain = AppDomain.CreateDomain("TestDomain", null, setup);  
        string name = Assembly.GetExecutingAssembly().GetName().FullName;  
        remoteLoader = (RemoteLoader)appDomain.CreateInstanceAndUnwrap(  
            name,  
            typeof(RemoteLoader).FullName);  
    }  
    public void LoadAssembly(string fullName)  
    {  
        remoteLoader.LoadAssembly(fullName);  
    }  
    public void Unload()  
    {  
        AppDomain.Unload(appDomain);  
        appDomain = null;  
    }  
    public string FullName  
    {  
        get  
        {  
            return remoteLoader.FullName;  
        }  
    }  
}
로그인 후 복사


  • 마지막으로 WinForm의 버튼 클릭이벤트 처리 프로세스를 다음 형식으로 수정합니다. :

아아앙



위 수정을 완료한 후 우리 프로그램은 어셈블리의 FullName을 올바르게 표시할 수도 있습니다. 또한 어셈블리 정보를 표시한 후 프로그램은 새로 생성된 AppDomain을 적극적으로 제거하여 testlib.dll이 리소스를 독점하고 작업에 영향을 미치는 것을 방지합니다. 다른 프로그램의 .

위 내용은 AppDomain 및 Assembly의 동적 로드 및 언로드 코드에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿