.NET Core中没有AppDomains!为什么?


86

微软为什么不选择在.NET Core中支持AppDomains的理由很充分?

当构建长时间运行的服务器应用程序时,AppDomains尤其有用,在这种情况下,我们可能希望以合适的方式更新服务器加载的程序集,而无需关闭服务器。

如果没有AppDomains,我们将如何在长时间运行的服务器进程中替换程序集?

AppDomains还为我们提供了一种隔离服务器代码不同部分的方法。就像,自定义Websocket服务器可以在主应用程序域中具有套接字代码,而我们的服务则在辅助应用程序域中运行。

如果没有AppDomains,则不可能出现上述情况。

我可以看到一个论点,它可能涉及使用VM的Cloud概念来处理程序集更改,而不必承担AppDomains的开销。但这是微软的想法或说法吗?还是他们有上述情况的特定原因和替代方案?


9
但是.NET Core 5不是.NET Framework。它不是即将发布的.NET CLR 4.6版本,但是别担心,AppDomain仍然可以使用。
阿德里亚诺·雷佩蒂

2
我知道了,但是如果Microsoft声称.NET Core 5将是多平台(Windows / Linux / Unix),那么我很好奇他们为什么要删除AppDomain等核心功能。
Aditya Pasumarthi 2014年

3
我猜(但这只是我的看法),它们很难以多平台的方式实现,它们减慢了很多事情的速度并增加了复杂性。没有多少人使用它们(至少大多数人不直接使用它们)。如果不需要它们,则可以使用.NET Core。如果您需要它们...请不要使用它(考虑ReFS与NTFS)。简而言之,.NET Core并不是.NET的未来(到目前为止),而是一个单独的项目。也许是一个工作台,但肯定不是迁移路径或1:1替代方案(至少现在是这样)。
Adriano Repetti 2014年

@AdrianoRepetti:考虑添加这个作为答案,因为我认为这样很有用。
Patrick Hofman 2014年

@PatrickHofman这只是我的意见(第二条评论),我可以作为社区Wiki来回答,但我会将这项职责留给英语更加流利的人!
Adriano Repetti 2014年

Answers:


50

.NETCore子集的目的是使.NET安装保持较小。而且容易移植。这就是为什么您可以在Windows和OSX上都运行Silverlight应用程序,而又不用等待很长时间就能访问网页的原因。下载或安装完整的运行时和框架需要花费几秒钟的时间。

缩小尺寸不可避免地需要削减特征。在该列表中,远程处理非常重要,这非常昂贵。否则隐藏得很好,但是例如您可以看到委托不再具有功能性的BeginInvoke()方法。这也将AppDomain列在清单上,如果没有远程支持,您将无法在应用程序域中运行代码。因此,这完全是设计使然。


12
恕我直言,它与大小无关,但事实上CoreCLR没有强大的命名功能,因此具有新的融合系统和新的方式来查看程序集是什么,其标识以及它在哪里加载,表示将appdomain用作容器不再有用。
弗朗斯·布玛

7
嗯不 将下载大小保持为6.6 MB当然需要删除多个功能。
汉斯·帕桑

7
即使您未使用强命名,AppDomains在完整的.NET中也很有用。(例如,AppDomain提供故障隔离的能力并不取决于强命名。)因此,强命名的删除本身并不是删除AppDomain的原因。
伊恩·格里菲斯

5
我糊涂了。.Net Core和Silverlight之间是什么关系?
svick

10
程序员倾向于假设.NETCore是新的。Microsoft几乎没有采取任何行动来消除这一观念,至少没有将5.0版本号更改为1.0。CoreCLR已经存在了很长的时间,并且从.NET Compact的运行时开始。Silverlight和WinRT / UWP运行时是开源的显着用途。最佳选择的运行时版本,以前已经移植到OSX和各种WinCE移动处理器。
汉斯·帕桑

46

.NET Standard 2和.NET Core 2的更新

在.NET标准2AppDomain在那里。但是,该API的许多部分都将为PlatformNotSupportedException.NET Core抛出一个。

它仍然存在的主要原因是一些基本的东西,例如注册一个可以正常工作的未处理的异常处理程序。

.NET标准常见问题解答具有以下解释

AppDomain是.NET Standard的一部分吗?

AppDomain类型是.NET Standard的一部分。并非所有平台都支持创建新的应用程序域,例如,.NET Core不支持。因此,.NET Standard中可用的AppDomain.CreateDomain方法可能会抛出PlatformNotSupportedException。

我们在.NET Standard中公开此类型的主要原因是因为使用率很高,通常与创建新的应用程序域无关,而是与当前应用程序域进行交互,例如注册未处理的异常处理程序或请求应用程序的基本目录。

除此之外,最上面的答案和其他答案还很好地解释了为何仍然削减了大部分AppDomain(例如,引发了不受支持的异常)。


20

应用程序域

为什么停产了?AppDomains需要运行时支持,并且通常很昂贵。尽管仍由CoreCLR实施,但.NET Native中不提供此功能,我们不打算在此处添加此功能。

我应该怎么用呢?AppDomains用于不同的目的。对于代码隔离,我们建议使用进程和/或容器。对于程序集的动态加载,我们建议使用新的AssemblyLoadContext类。

来自MSDN博客的来源


一个问题,您的意思For code isolation, we recommend processes and/or containers是什么?.net核心中是否有可用的容器api?
伊万德罗·饶

@IvandroIsmael,他们的意思是“你的单一的应用程序/模块拆分为单独的交互应用程序/模块/流程/容器”(最有可能-到微服务),即重构你的应用程序不能使用应用程序域代码隔离
突发

10

有一次,我听说不使用域就可以启用卸载程序集。我认为System.Runtime.Loader.AssemblyLoadContextSystem.Runtime.Loader.dll中的类型与此工作有关,但我看不到任何能够卸载的内容。


5

我曾在社区演讲或Microsoft谈话中听说,AppDomains的隔离功能可以由进程(以及其他平台中的常见模式)更好地处理,并且卸载确实是计划中与AppDomains不相关的常规功能。


5

您不再需要AppDomain,现在有了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()
     {}
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.