Adi*_*thi 72 .net clr appdomain .net-core
微软是否有理由选择不支持.NET Core中的AppDomains?
AppDomains在构建长时间运行的服务器应用程序时特别有用,我们可能希望更新服务器加载的程序集是一种优雅的方式,而无需关闭服务器.
如果没有AppDomains,我们如何在长时间运行的服务器进程中替换我们的程序集?
AppDomains还为我们提供了一种隔离服务器代码不同部分的方法.比如,自定义websocket服务器可以在主appdomain中具有套接字代码,而我们的服务在辅助appdomain中运行.
如果没有AppDomains,则无法使用上述方案.
我可以看到一个论点,可能会讨论使用VM的云概念来处理程序集更改而不必承担AppDomains的开销.但这是微软的想法或说法吗?或者他们有针对上述情况的具体原因和替代方案?
Han*_*ant 44
.NETCore子集的要点是保持.NET安装的小.并且易于移植.这就是为什么你可以在Windows和OSX上运行Silverlight应用程序,而不是在访问网页时等待很长时间.下载和安装完整的运行时和框架需要花费一些时间,给予或接受.
保持小巧不可避免地需要削减功能.Remoting在这个名单上非常高,它非常昂贵.否则很好地隐藏,但您可以看到委托不再具有功能的BeginInvoke()方法.这也将AppDomain放在剪切列表中,如果没有远程支持,则无法在app域中运行代码.所以这完全是设计的.
Jer*_*oen 38
在.NET Standard 2中,AppDomain类就在那里.但是,该API的许多部分都将引发PlatformNotSupportedException.NET Core.
它仍然在那里的主要原因是对于像注册一个未处理的异常处理这些基本的东西会工作.
AppDomain是.NET Standard的一部分吗?
AppDomain类型是.NET Standard的一部分.并非所有平台都支持创建新的应用程序域,例如,.NET Core不会,因此在.NET Standard中可用的方法AppDomain.CreateDomain可能会抛出PlatformNotSupportedException.
我们在.NET Standard中公开此类型的主要原因是因为使用率相当高并且通常与创建新的应用程序域无关,而是与当前应用程序域进行交互,例如注册未处理的异常处理程序或要求应用程序的基本目录.
除此之外,最佳答案和其他答案也很好地解释了为什么大部分AppDomain仍被切断(例如抛出一个不支持的异常).
有一次,我听说将在不使用域的情况下启用卸载程序集.我认为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"
Run Code Online (Sandbox Code Playgroud)
然后你可以说
eval.LoadContext.Unload();
eval.Stream.Dispose();
Run Code Online (Sandbox Code Playgroud)
如果你把它放到抽象类的 IDisposable 接口中,那么你可以使用 using,如果你愿意的话。
注意:
这假设在公共程序集中有一个固定的抽象类
public abstract class MyAbstractClass
{
public virtual void foo()
{}
}
Run Code Online (Sandbox Code Playgroud)
和动态运行时生成的类(使用 Roslyn),引用公共程序集中的抽象类,它实现例如:
public class RsEval: MyAbstractClass
{
public override void foo()
{}
}
Run Code Online (Sandbox Code Playgroud)
我在社区站会或微软的一些讨论中听说 AppDomains 的隔离功能更好地由进程处理(实际上是其他平台中的常见模式),并且卸载确实被计划为与 AppDomains 无关的正常功能。
| 归档时间: |
|
| 查看次数: |
21282 次 |
| 最近记录: |