Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.NET Core中没有AppDomains!为什么?_.net_Clr_Appdomain_.net Core - Fatal编程技术网

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

.NET Core中没有AppDomains!为什么?,.net,clr,appdomain,.net-core,.net,Clr,Appdomain,.net Core,Microsoft选择不支持.NET Core中的AppDomains有什么强烈的原因吗 在构建长时间运行的服务器应用程序时,AppDomains特别有用,在这种情况下,我们可能希望更新服务器加载的程序集是一种优雅的方式,而不关闭服务器 如果没有AppDomains,我们将如何在长时间运行的服务器进程中替换程序集 AppDomains还为我们提供了一种隔离服务器代码不同部分的方法。与此类似,自定义websocket服务器可以在主appdomain中具有套接字代码,而我们的服务在辅助appdoma

Microsoft选择不支持.NET Core中的AppDomains有什么强烈的原因吗

在构建长时间运行的服务器应用程序时,AppDomains特别有用,在这种情况下,我们可能希望更新服务器加载的程序集是一种优雅的方式,而不关闭服务器

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

AppDomains还为我们提供了一种隔离服务器代码不同部分的方法。与此类似,自定义websocket服务器可以在主appdomain中具有套接字代码,而我们的服务在辅助appdomain中运行

如果没有AppDomains,上述场景是不可能的


我可以看到一个论点,它可能讨论使用云的VMs概念来处理程序集更改,而不必产生AppDomains的开销。但这是微软的想法还是说法?或者他们对上述场景有特定的原因和备选方案?

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


保持小尺寸不可避免地需要裁剪特征。远程处理在这个列表中非常重要,它非常昂贵。否则会很好地隐藏,但您可以看到,例如,委托不再具有函数BeginInvoke()方法。这也将AppDomain放在了剪切列表中,如果没有远程处理支持,您无法在应用程序域中运行代码。所以这完全是出于设计。

有一次,我听说卸载程序集将在不使用域的情况下启用。我认为System.Runtime.Loader.AssemblyLoadContext中的
System.Runtime.Loader.dll类型与这项工作有关,但我还没有看到任何支持卸载的内容。

我在社区站或Microsoft的一些讨论中听说,AppDomains的隔离功能由进程更好地处理(实际上是其他平台中的常见模式),卸载实际上是作为与AppDomains无关的正常功能进行规划的

应用程序域 为什么停止使用?AppDomains需要运行时支持,而且通常非常昂贵。虽然仍由CoreCLR实现,但它在.NET Native中不可用,我们不打算在那里添加此功能

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

更新.NET标准2和.NET核心2 在.NET标准2中,
AppDomain
类就在其中。但是,该API的许多部分会为.NET核心抛出一个
PlatformNotSupportedException

它仍然存在的主要原因是一些基本的东西,比如注册一个未处理的异常处理程序

:

AppDomain是.NET标准的一部分吗

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

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


除此之外,和其他答案也很好地解释了为什么大部分AppDomain仍然被削减(例如抛出一个不受支持的异常)。

您不再需要AppDomains,您现在有了LoadContext:

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

但是.NET Core 5不是.NET Framework。它不是即将推出的.NET CLR 4.6版本,而是另一个独立的版本。那么别担心,AppDomain会留下来。我知道,但如果Microsoft声称.NET Core 5将是多平台(Windows/Linux/Unix),那么我很好奇他们为什么要删除AppDomain这样的核心功能。我猜(但这只是我的观点)它们更难以多平台的方式实现,它们减慢了许多事情并增加了复杂性。没有太多人使用它们(至少大多数人不会直接使用)。如果你不需要它们,你可以使用.NET Core。如果你需要它们…不要使用它(想想ReFS和NTFS)。简单地说,.NET Core不是.NET的未来(到目前为止)但是一个单独的项目。可能是一个工作台,但肯定不是迁移路径或1:1替代(至少现在)。@ AdRiaRoRePeTe:考虑把它作为一个答案,因为我认为它是有用的。@帕特里克霍夫曼,这只是我的意见(第二评论)。,我可以回答为community wiki,但我把这个职责留给了英语更流利的人!我认为这与大小无关,但事实上CoreCLR没有强命名,因此有了一个新的融合系统和一种新的方式来查看程序集是什么、它的标识以及它加载到哪里,这意味着appdomain是一个容器s不再有用。嗯,不。将下载大小保持在6.6MB当然需要删除多个功能。AppDomains在完整的.NET中可能很有用,即使您不使用强命名。(例如,AppDomains提供故障隔离的能力不依赖于强命名。)因此,删除强命名本身并不是删除的理由