.NET Core'da AppDomains yok! Neden?


88

Microsoft'un .NET Core'da AppDomains'i desteklememesinin güçlü bir nedeni var mı?

AppDomains, sunucu tarafından yüklenen derlemeleri, sunucuyu kapatmadan zarif bir şekilde güncellemek isteyebileceğimiz uzun çalışan sunucu uygulamaları oluştururken özellikle yararlıdır.

AppDomains olmadan, uzun süren bir sunucu sürecinde montajlarımızı nasıl değiştireceğiz?

AppDomains ayrıca bize sunucu kodunun farklı bölümlerini izole etmenin bir yolunu sunar. Örneğin, özel bir websocket sunucusu birincil uygulama alanında soket koduna sahipken, hizmetlerimiz ikincil uygulama alanında çalışır.

AppDomains olmadan yukarıdaki senaryo mümkün değildir.

Montaj değişikliklerini ele almak ve AppDomains'in ek yüküne maruz kalmak zorunda kalmamak için VM'lerin Cloud kavramını kullanma hakkında konuşabilecek bir argüman görebiliyorum. Ancak Microsoft'un düşündüğü veya söylediği bu mu? veya yukarıdaki senaryolar için belirli bir nedenleri ve alternatifleri var mı?


9
Ancak .NET Core 5 , .NET Framework değildir . NET CLR 4.6'nın yaklaşan sürümü değil , ancak başka bir ayrı şey daha sonra endişelenmeyin, AppDomain burada kalacak.
Adriano Repetti

2
Bunu görüyorum, ancak Microsoft .NET Core 5'in çoklu platform (Windows / Linux / Unix) olacağını iddia ediyorsa, o zaman neden AppDomain gibi bir çekirdek özelliği kaldırmak istediklerini merak ediyorum.
Aditya Pasumarthi

3
Sanırım (ama sadece benim fikrim) çoklu platformda uygulanması daha zor, birçok şeyi yavaşlatıyor ve karmaşıklık katıyorlar. Pek çok insan bunları kullanmıyor (en azından çoğu insan bunu doğrudan yapmıyor). İhtiyacınız yoksa .NET Core'u kullanabilirsiniz. İhtiyacınız varsa ... kullanmayın (ReFS ​​ve NTFS'yi düşünün). Basitçe .NET Core, .NET geleceği değil (şimdiye kadar) ayrı bir proje. Belki bir çalışma tezgahı ama kesinlikle bir geçiş yolu veya 1: 1 alternatif değil (en azından şimdi).
Adriano Repetti

@AdrianoRepetti: Faydalı olduğunu düşündüğüm için bunu bir cevap olarak eklemeyi düşünün.
Patrick Hofman

@PatrickHofman bu sadece benim fikrim (2. yorum), topluluk wiki olarak cevap verebilirim ama bu görevi daha akıcı bir İngilizcesi olan birine bırakıyorum !
Adriano Repetti

Yanıtlar:


49

.NETCore alt kümesinin amacı, .NET kurulumunu küçük tutmaktı. . Ve taşınması kolay. Bu nedenle, diyelim ki hem Windows hem de OSX'te bir Silverlight uygulaması çalıştırabilir ve web sayfasını ziyaret ettiğinizde çok uzun süre beklemeyebilirsiniz. Tam çalışma zamanını ve çerçeveyi indirmek ve kurmak birkaç saniye sürer, ister verin ister alın.

Küçük tutmak, kaçınılmaz olarak özelliklerin kesilmesini gerektirir. Remoting bu listede çok yüksekti, oldukça pahalı. Aksi takdirde iyi gizlenir, ancak örneğin temsilcilerin artık işlevsel bir BeginInvoke () yöntemine sahip olmadığını görebilirsiniz. Bu, AppDomain'i de kesim listesine koydu, uzaktan destek olmadan bir uygulama alanında kod çalıştıramazsınız. Yani bu tamamen tasarım gereğidir.


13
IMHO'nun boyutla ilgisi yoktur, ancak CoreCLR'nin güçlü bir isimlendirmeye sahip olmadığı ve dolayısıyla yeni bir füzyon sistemine ve bir montajın ne olduğuna, kimliğine ve nereye yüklendiğine yeni bir bakış açısına sahip olduğu gerçeğiyle, Yani bir kapsayıcı olarak appdomain artık kullanışlı değil.
Frans Bouma

7
Hmm, hayır. İndirme boyutunu 6,6 MB'de tutmak, elbette birden fazla özelliğin kaldırılmasını gerektiriyordu.
Hans Passant

8
AppDomains, güçlü adlandırma kullanmasanız bile tam .NET'te yararlı olabilir. (Örneğin, AppDomains'in hata izolasyonu sağlama yeteneği, güçlü adlandırmaya bağlı değildir.) Bu nedenle, güçlü adlandırmanın kaldırılması, AppDomains'i kaldırmak için tek başına bir neden olmayacaktır.
Ian Griffiths

5
Kafam karıştı. .Net Core ve Silverlight arasındaki ilişki nedir?
svick

10
Programcılar .NETCore'un yeni olduğunu varsayma eğilimindedir. Microsoft, 5.0 sürüm numarasını 1.0 olarak değiştirerek bu fikri ortadan kaldırmak için çok az şey yapar. CoreCLR çok uzun zamandır ortalıkta, .NET Compact için çalışma zamanı olarak hayata başladı. Silverlight ve WinRT / UWP çalışma zamanı, açık kaynaklı olmadan önce onun için dikkate değer kullanımlardır. Daha önce OSX ve çeşitli WinCE mobil işlemcilerine zaten taşınmış olan, seçilebilecek en iyi çalışma zamanı sürümü.
Hans Passant

47

.NET Standard 2 ve .NET Core 2 için güncelleştirme

.NET Standart 2'de AppDomainsınıf olduğunu içeride. Ancak, bu API'nin birçok parçası birPlatformNotSupportedException for .NET Core .

Hala orada olmasının ana nedeni , işe yarayacak bir işlenmemiş istisna işleyicisini kaydetmek gibi temel şeyler içindir .

.NET Standard SSS'de şu açıklama bulunur :

AppDomain, .NET Standard'ın bir parçası mı?

AppDomain türü .NET Standard'ın bir parçasıdır. Tüm platformlar yeni uygulama etki alanlarının oluşturulmasını desteklemez; örneğin, .NET Core desteklemez, bu nedenle .NET Standard'da kullanılabilirken AppDomain.CreateDomain yöntemi PlatformNotSupportedException oluşturabilir.

Bu türü .NET Standard'da göstermemizin birincil nedeni, kullanımın oldukça yüksek olması ve genellikle yeni uygulama etki alanları oluşturmakla ilişkili olmaması, ancak işlenmemiş bir istisna işleyicisinin kaydedilmesi veya uygulamanın temel dizinini istemek gibi mevcut uygulama etki alanıyla etkileşimde bulunmaktır. .

Bunun dışında, en iyi cevap ve diğer cevaplar, AppDomain'in büyük kısmının neden hala kesildiğini de güzel bir şekilde açıklıyor (örneğin, desteklenmeyen bir istisna atıyor).


21

Uygulama Alanları

Neden durduruldu? AppDomains, çalışma zamanı desteği gerektirir ve genellikle oldukça pahalıdır. Hala CoreCLR tarafından uygulanmasına rağmen, .NET Native'de mevcut değildir ve bu özelliği oraya eklemeyi planlamıyoruz.

Onun yerine ne kullanmalıyım? AppDomains farklı amaçlar için kullanıldı. Kod izolasyonu için süreçleri ve / veya kapsayıcıları öneriyoruz. Derlemelerin dinamik yüklenmesi için, yeni AssemblyLoadContext sınıfını öneririz.

MSDN Blogundan Kaynak


Bir soru, neyi kastediyorsunuz For code isolation, we recommend processes and/or containers... .net çekirdeğinde bir konteyner api var mı?
Ivandro Jao

@IvandroIsmael, "tek uygulamanızı / modülünüzü etkileşimli ayrı uygulamalara / modüllere / işlemlere / kapsayıcılara bölmek" anlamına gelir (büyük olasılıkla - mikro hizmetlere), yani uygulamanızı kod izolasyonu için AppDomains'i kullanmayacak şekilde yeniden düzenleyin
Patlama

10

Bir noktada, boşaltma montajlarının etki alanları kullanılmadan etkinleştirileceğini duydum. System.Runtime.Loader.AssemblyLoadContextSystem.Runtime.Loader.dll'deki türün bu işle ilgili olduğunu düşünüyorum , ancak henüz boşaltmayı sağlayan hiçbir şey görmüyorum.


6

Artık AppDomains'e ihtiyacınız yok, artık LoadContexts'e sahipsiniz:

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"

ve sonra söyleyebilirsin

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

Bonus, eğer bunu soyut sınıfın IDisposable arayüzüne koyarsanız, o zaman isterseniz kullanabilirsiniz.

Not:
Bu, ortak bir derlemede sabit bir soyut sınıf olduğunu varsayar

public abstract class MyAbstractClass 
{

     public virtual void foo()
     {}
}

ve dinamik olarak çalışma zamanında oluşturulmuş bir sınıf (Roslyn kullanarak), ortak derlemedeki soyut sınıfa atıfta bulunarak, örneğin:

public class RsEval: MyAbstractClass 
{

     public override void foo()
     {}
}

5

Bir topluluk standup'ında veya Microsoft'tan bazı konuşmalarda, AppDomains'in yalıtım özelliğinin süreçler tarafından daha iyi ele alındığını (ve aslında diğer platformlardaki ortak model) ve boşaltmanın gerçekten de AppDomains ile ilgisi olmayan normal bir özellik olarak planlandığını duydum.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.