.NET Core에 AppDomain이 없습니다! 왜?


88

Microsoft가 .NET Core에서 AppDomains를 지원하지 않기로 선택한 강력한 이유가 있습니까?

AppDomains는 서버를 종료하지 않고 서버에서로드 한 어셈블리를 적절하게 업데이트하려는 장기 실행 서버 앱을 빌드 할 때 특히 유용합니다.

AppDomains가 없으면 장기 실행 서버 프로세스에서 어셈블리를 어떻게 교체할까요?

AppDomains는 또한 서버 코드의 다른 부분을 격리하는 방법을 제공합니다. 마찬가지로 사용자 지정 웹 소켓 서버는 기본 appdomain에 소켓 코드를 가질 수 있지만 서비스는 보조 appdomain에서 실행됩니다.

AppDomains가 없으면 위의 시나리오는 불가능합니다.

어셈블리 변경을 처리하고 AppDomain의 오버 헤드를 발생시키지 않아도되는 클라우드의 VM 개념을 사용하는 것에 대해 이야기 할 수있는 주장을 볼 수 있습니다. 그러나 이것이 Microsoft가 생각하거나 말하는 것입니까? 또는 위 시나리오에 대한 구체적인 이유와 대안이 있습니까?


9
그러나 .NET Core 5 .NET Framework 가 아닙니다 . 그렇지 않은 .NET CLR 4.6의 향후 버전 하지만 다른 별도의 일이 다음하지 걱정을, 응용 프로그램 도메인은 여기에 있습니다.
아드리아누 Repetti

2
하지만 Microsoft가 .NET Core 5가 다중 플랫폼 (Windows / Linux / Unix)이 될 것이라고 주장하는 경우 AppDomain과 같은 핵심 기능을 제거하려는 이유가 궁금합니다.
Aditya Pasumarthi

3
나는 (그러나 그것은 단지 내 의견이다) 다중 플랫폼 방식으로 구현하기가 더 어렵고 많은 것을 느리게 만들고 복잡성을 추가합니다. 많은 사람들이 사용하지 않습니다 (적어도 대부분의 사람들은 직접 사용하지 않습니다). 필요하지 않은 경우 .NET Core를 사용할 수 있습니다. 필요한 경우 사용하지 마십시오 (ReFS ​​대 NTFS를 생각하십시오). 단순히 .NET Core는 .NET 미래 (지금까지)가 아니라 별도의 프로젝트입니다. 워크 벤치 일 수도 있지만 마이그레이션 경로 나 1 : 1 대안은 아닙니다 (적어도 지금).
Adriano Repetti 2014

@AdrianoRepetti : 이것이 유용하다고 생각하기 때문에 이것을 대답으로 추가하는 것을 고려하십시오.
Patrick Hofman 2014

@PatrickHofman 그것은, 내가 커뮤니티 위키로 대답 할 수 단지 내 의견 (2 코멘트)이다하지만이 떠나 의무를 더 유창하게 영어를 사람에게!
Adriano Repetti 2014

답변:


49

.NETCore 하위 집합의 요점은 .NET 설치를 작게 유지하는 것이 었습니다 . 이식하기 쉽습니다. 그렇기 때문에 Windows와 OSX 모두에서 Silverlight 앱을 실행할 수 있고 웹 페이지를 방문 할 때 오래 기다리지 않아도됩니다. 완전한 런타임과 프레임 워크를 다운로드하고 설치하는 데는 몇 초 정도 걸립니다.

작게 유지하려면 불가피하게 기능을 잘라야합니다. Remoting은 그 목록에서 매우 높았으며 비용이 많이 듭니다. 그렇지 않으면 잘 숨겨져 있지만 예를 들어 대리자에 더 이상 기능적인 BeginInvoke () 메서드가 없음을 알 수 있습니다. AppDomain도 컷 목록에 포함되므로 원격 지원 없이는 앱 도메인에서 코드를 실행할 수 없습니다. 그래서 이것은 전적으로 의도적으로 설계된 것입니다.


13
IMHO는 크기와 관련이 없지만 CoreCLR에는 강력한 이름 지정이 없으므로 새로운 융합 시스템과 어셈블리가 무엇인지, 그 정체성과로드 위치를 보는 새로운 방식이 있다는 사실과 관련이 있습니다. 즉, 컨테이너로서의 appdomain은 더 이상 유용하지 않습니다.
Frans Bouma 2014

7
흠, 아니. 물론 다운로드 크기를 6.6MB로 유지하려면 둘 이상의 기능을 제거해야했습니다.
Hans Passant 2014

8
강력한 이름 지정을 사용하지 않는 경우에도 전체 .NET에서 AppDomains가 유용 할 수 있습니다. (예를 들어, 오류 격리를 제공하는 AppDomains의 기능은 강력한 이름 지정에 의존하지 않습니다.) 따라서 강력한 이름 지정의 제거 자체가 AppDomains를 제거하는 이유는 아닙니다.
Ian Griffiths

5
혼란 스러워요. .Net Core와 Silverlight의 관계는 무엇입니까?
svick

10
프로그래머는 .NETCore가 새로운 것이라고 생각하는 경향이 있습니다. Microsoft는 5.0 버전 번호를 1.0으로 변경하는 것이 아니라이 개념을 거의 없애지 않습니다. CoreCLR은 아주 오래 전부터 .NET Compact의 런타임으로 시작되었습니다. Silverlight 및 WinRT / UWP 런타임은 오픈 소스 화되기 전에 주목할만한 용도입니다. 이전에 이미 OSX 및 다양한 WinCE 모바일 프로세서로 포팅 된 적이있는 최고의 런타임 버전입니다.
Hans Passant

47

.NET Standard 2 및 .NET Core 2 용 업데이트

.NET Standard 2에는 AppDomain클래스 있습니다. 그러나 해당 API의 많은 부분 PlatformNotSupportedException에서 .NET Core 용이 발생합니다.

그것이 여전히 존재하는 주된 이유 작동 할 처리되지 않은 예외 핸들러를 등록하는 것과 같은 기본적인 것들 때문입니다 .

.NET Standard FAQ에는 다음과 같은 설명이 있습니다 .

AppDomain은 .NET Standard의 일부입니까?

AppDomain 유형은 .NET Standard의 일부입니다. 모든 플랫폼이 새 앱 도메인 생성을 지원하는 것은 아닙니다. 예를 들어 .NET Core는 지원하지 않으므로 .NET Standard에서 사용 가능한 AppDomain.CreateDomain 메서드는 PlatformNotSupportedException을 throw 할 수 있습니다.

.NET Standard에서이 유형을 노출하는 주된 이유는 사용량이 상당히 높고 일반적으로 새 앱 도메인을 만드는 것과 관련이 없지만 처리되지 않은 예외 처리기를 등록하거나 애플리케이션의 기본 디렉터리를 요청하는 등 현재 앱 도메인과 상호 작용하기 때문입니다. .

그 외에도 상위 답변 및 기타 답변은 AppDomain의 대부분이 여전히 잘린 이유를 잘 설명합니다 (예 : 지원되지 않는 예외 발생).


21

앱 도메인

중단 된 이유는 무엇입니까? AppDomain은 런타임 지원이 필요하며 일반적으로 비용이 많이 듭니다. 여전히 CoreCLR에 의해 구현되지만 .NET Native에서는 사용할 수 없으며 여기에이 기능을 추가 할 계획이 없습니다.

대신 무엇을 사용해야합니까? AppDomain은 다른 목적으로 사용되었습니다. 코드 격리를 위해 프로세스 및 / 또는 컨테이너를 권장합니다. 어셈블리를 동적으로로드하려면 새 AssemblyLoadContext 클래스를 사용하는 것이 좋습니다.

MSDN 블로그 출처


한 가지 질문은 무엇을 의미 For code isolation, we recommend processes and/or containers합니까? .net 코어에서 사용할 수있는 컨테이너 API가 있습니까?
Ivandro Jao

@IvandroIsmael, "단일 앱 / 모듈을 별도의 상호 작용하는 앱 / 모듈 / 프로세스 / 컨테이너로 분할"(대부분 마이크로 서비스로 분할), 즉 코드 격리를 위해 AppDomains를 사용하지 않도록 앱을 리팩터링하는 것을 의미합니다.
Burst

10

언로드 어셈블리는 도메인을 사용하지 않고 활성화 될 것이라고 들었습니다. System.Runtime.Loader.AssemblyLoadContextSystem.Runtime.Loader.dll 의 형식이이 작업과 관련이 있다고 생각 하지만 아직 언로드 할 수있는 항목이 표시되지 않습니다.


6

더 이상 AppDomains가 필요하지 않습니다. 이제 LoadContexts가 있습니다.

public class CollectibleAssemblyLoadContext 
    : AssemblyLoadContext
{
    public CollectibleAssemblyLoadContext() : base(isCollectible: true)
    { }
 
    protected override Assembly Load(AssemblyName assemblyName)
    {
        return null;
    }
}

byte[] result = null; // Assembly Emit-result from roslyn
System.Runtime.Loader.AssemblyLoadContext context = new CollectibleAssemblyLoadContext();
System.IO.Stream ms = new System.IO.MemoryStream(result);
System.Reflection.Assembly assembly = context.LoadFromStream(ms);


System.Type programType = assembly.GetType("RsEval");
MyAbstractClass eval = (MyAbstractClass )System.Activator.CreateInstance(programType);
eval.LoadContext = context;
eval.Stream = ms;
// do something here with the dynamically created class "eval"

그리고 당신은 말할 수 있습니다

eval.LoadContext.Unload();
eval.Stream.Dispose();

추상 클래스의 IDisposable 인터페이스에 추가하면 원하는 경우 using을 사용할 수 있습니다.

참고 :
이것은 공통 어셈블리에서 고정 된 추상 클래스를 가정합니다.

public abstract class MyAbstractClass 
{

     public virtual void foo()
     {}
}

다음을 구현하는 공통 어셈블리의 추상 클래스를 참조하는 동적 런타임 생성 클래스 (Roslyn 사용)가 있습니다.

public class RsEval: MyAbstractClass 
{

     public override void foo()
     {}
}

5

나는 커뮤니티 스탠드 업이나 마이크로 소프트에서 AppDomains의 격리 기능이 프로세스 (그리고 실제로는 다른 플랫폼의 일반적인 패턴)에서 더 잘 처리되며 언 로딩은 실제로 AppDomains와 관련이없는 정상적인 기능으로 계획되어 있다고 들었습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.