.NET Core 中没有 AppDomains!为什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27266907/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
No AppDomains in .NET Core! Why?
提问by Aditya Pasumarthi
Is there a strong reason why Microsoft chose not to support AppDomains in .NET Core?
Microsoft 选择不支持 .NET Core 中的 AppDomains 是否有充分的理由?
AppDomains are particularly useful when building long running server apps, where we may want to update the assemblies loaded by the server is a graceful manner, without shutting down the server.
AppDomains 在构建长时间运行的服务器应用程序时特别有用,我们可能希望以一种优雅的方式更新服务器加载的程序集,而无需关闭服务器。
Without AppDomains, how are we going to replace our assemblies in a long running server process?
如果没有 AppDomains,我们将如何在长时间运行的服务器进程中替换我们的程序集?
AppDomains also provide us a way to isolate different parts of server code. Like, a custom websocket server can have socket code in primary appdomain, while our services run in secondary appdomain.
AppDomains 还为我们提供了一种隔离服务器代码不同部分的方法。就像,自定义 websocket 服务器可以在主 appdomain 中拥有套接字代码,而我们的服务在辅助 appdomain 中运行。
Without AppDomains, the above scenario is not possible.
没有 AppDomains,上述场景是不可能的。
I can see an argument that may talk about using VMs concept of Cloud for handling assembly changes and not having to incur the overhead of AppDomains. But is this what Microsoft thinks or says? or they have a specific reason and alternatives for the above scenarios?
我可以看到一个论点可能会谈论使用云的 VM 概念来处理程序集更改,而不必招致 AppDomains 的开销。但这是微软的想法或说法吗?或者他们对上述情况有特定的原因和替代方案?
回答by Hans Passant
The point of the .NETCore subset was to keep a .NET install small. And easy to port. Which is why you can, say, run a Silverlight app on both Windows and OSX and not wait very long when you visit the web page. Downloading and installing the complete runtime and framework takes a handful of seconds, give or take.
.NETCore 子集的重点是保持 .NET 安装小。并且易于移植。这就是为什么您可以在 Windows 和 OSX 上运行 Silverlight 应用程序,而无需在访问网页时等待很长时间。下载和安装完整的运行时和框架需要几秒钟的时间。
Keeping it small inevitably requires features to be cut. Remoting was very high on that list, it is quite expensive. Otherwise well hidden, but you can for example see that delegates no longer have a functional BeginInvoke() method. Which put AppDomain on the cut list as well, you can't run code in an app domain without remoting support. So this is entirely by design.
保持小规模不可避免地需要削减特征。远程处理在该列表中非常高,它非常昂贵。否则隐藏得很好,但是例如您可以看到委托不再具有功能性的 BeginInvoke() 方法。这也将 AppDomain 列入了清单,如果没有远程支持,您就无法在应用程序域中运行代码。所以这完全是设计使然。
回答by Jeroen
Update for .NET Standard 2 and .NET Core 2
.NET Standard 2 和 .NET Core 2 的更新
In .NET Standard 2 the AppDomainclass isin there. However, many parts of that API will throw a PlatformNotSupportedExceptionfor .NET Core.
在 .NET Standard 2 中,AppDomain类就在那里。但是,该 API 的许多部分会PlatformNotSupportedException为 .NET Core抛出一个错误。
The main reason it's still in there is for basic stuff like registering an unhandled exception handler which willwork.
它仍然存在的主要原因是基本的东西,比如注册一个可以工作的未处理的异常处理程序。
The .NET Standard FAQ has this explanation:
Is AppDomain part of .NET Standard?
The AppDomain type is part of .NET Standard. Not all platforms will support the creation of new app domains, for example, .NET Core will not, so the method AppDomain.CreateDomain while being available in .NET Standard might throw PlatformNotSupportedException.
The primary reason we expose this type in .NET Standard is because the usage is fairly high and typically not associated with creating new app domains but for interacting with the current app domain, such as registering an unhandled exception handler or asking for the application's base directory.
AppDomain 是 .NET Standard 的一部分吗?
AppDomain 类型是 .NET Standard 的一部分。并非所有平台都支持创建新的应用程序域,例如,.NET Core 不会,因此方法 AppDomain.CreateDomain 在 .NET Standard 中可用时可能会抛出 PlatformNotSupportedException。
我们在 .NET Standard 中公开这种类型的主要原因是因为使用率相当高,通常与创建新的应用程序域无关,而是用于与当前应用程序域进行交互,例如注册未处理的异常处理程序或请求应用程序的基目录.
Apart from that, the top answerand other answers also nicely explain why the bulk of AppDomain was still cut (e.g. throws a not supported exception).
除此之外,顶级答案和其他答案也很好地解释了为什么 AppDomain 的大部分仍然被削减(例如抛出不受支持的异常)。
回答by cwishva
App Domains
应用程序域
Why was it discontinued?AppDomains require runtime support and are generally quite expensive. While still implemented by CoreCLR, it's not available in .NET Native and we don't plan on adding this capability there.
为什么停产了?AppDomains 需要运行时支持并且通常非常昂贵。虽然仍由 CoreCLR 实现,但它在 .NET Native 中不可用,我们不打算在那里添加此功能。
What should I use instead?AppDomains were used for different purposes. For code isolation, we recommend processes and/or containers. For dynamic loading of assemblies, we recommend the new AssemblyLoadContext class.
我应该用什么代替?AppDomains 用于不同的目的。对于代码隔离,我们推荐进程和/或容器。对于程序集的动态加载,我们建议使用新的 AssemblyLoadContext 类。
回答by bricelam
At one point, I heard that unloading assemblies would be enabled without using domains. I think that the System.Runtime.Loader.AssemblyLoadContexttype in System.Runtime.Loader.dll is related to this work, but I don't see anything there that enables unloading yet.
有一次,我听说可以在不使用域的情况下启用卸载程序集。我认为System.Runtime.Loader.AssemblyLoadContextSystem.Runtime.Loader.dll中的类型与这项工作有关,但我还没有看到任何可以卸载的内容。
回答by Thomas
I have heard in a community standup or some talk of Microsoft that the isolation feature of AppDomains are better handled by processes (and actually the common pattern in other platforms) and the unloading is indeed planned as a normal feature unrelated to AppDomains.
我在社区站会或微软的一些讨论中听说 AppDomains 的隔离功能更好地由进程处理(实际上是其他平台中的常见模式),并且卸载确实被计划为与 AppDomains 无关的正常功能。
回答by Stefan Steiger
You don't need AppDomains anymore, you now have LoadContexts:
您不再需要 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"
and then you can say
然后你可以说
eval.LoadContext.Unload();
eval.Stream.Dispose();
Bonus if you put that into the IDisposable interface of the abstract class, then you can just use using, if you want to.
如果你把它放到抽象类的 IDisposable 接口中,那么你可以使用 using,如果你愿意的话。

