태그 보관물: appdomain

appdomain

.NET Core에 AppDomain이 없습니다! 왜? Microsoft가 .NET Core에서 AppDomains를 지원하지 않기로 선택한

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

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

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

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

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

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



답변

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

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


답변

.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의 대부분이 여전히 잘린 이유를 잘 설명합니다 (예 : 지원되지 않는 예외 발생).


답변

앱 도메인

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

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

MSDN 블로그 출처


답변

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


답변

더 이상 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()
     {}
}


답변

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


답변