当前位置:  开发笔记 > 编程语言 > 正文

如何从主AppDomain卸载程序集?

如何解决《如何从主AppDomain卸载程序集?》经验,为你挑选了4个好方法。

我想知道如何卸载加载到主AppDomain中的程序集.

我有以下代码:

var assembly = Assembly.LoadFrom( FilePathHere );

当我完成时,我需要/希望能够卸载这个程序集.

谢谢你的帮助.



1> Philip Rieck..:

您无法从appdomain卸载程序集.您可以销毁appdomains,但是一旦将程序集加载到appdomain中,它就会存在于appdomain的生命周期中.

请参阅Jason Zander关于为何没有Assembly.Unload方法的解释?

如果您使用的是3.5,则可以使用AddIn Framework来更轻松地管理/调用不同的AppDomain(您可以卸载,卸载所有程序集).如果您之前使用的是版本,则需要自己创建一个新的appdomain来卸载它.



2> 小智..:

我也知道这已经很老了,但可能会帮助有这个问题的人!这是我发现的一种方法!而不是使用:

var assembly = Assembly.LoadFrom( FilePathHere );

用这个:

var assembly = Assembly.Load( File.ReadAllBytes(FilePathHere));

这实际上加载了程序集文件的"内容",而不是文件本身.这意味着程序集文件上没有文件锁!所以现在它可以复制,删除或升级而无需关闭您的应用程序或尝试使用单独的AppDomain或Marshaling!

PROS:使用1个代码修复非常简单! 缺点:不能使用AppDomain,Assembly.Location或Assembly.CodeBase.

现在您只需要销毁在程序集上创建的任何实例.例如:

assembly = null;



3> Mark Cidade..:

如果不卸载整个AppDomain,则无法卸载程序集.原因如下:

    您正在应用程序域中运行该代码.这意味着可能存在呼叫站点和调用堆栈,其中包含期望继续工作的地址.

    假设您确实设法跟踪程序集的所有句柄和对已运行代码的引用.假设您没有使用代码,一旦成功释放了程序集,您就只释放了元数据和IL.JIT代码仍然在app域加载器堆中分配(JIT'd方法按照调用它们的顺序在缓冲区中按顺序分配).

    最后一个问题涉及已加载共享的代码,否则更正式地称为"域中立"(在ngen工具上签出/共享).在此模式下,生成程序集的代码将从任何应用程序域执行(没有硬连线).

建议您自然地围绕应用程序域边界设计应用程序,完全支持卸载.



4> Nipun..:

您应该将临时程序集加载到另一个程序集中AppDomain,当不使用时,您可以卸载它AppDomain.这是安全和快速的.


请参阅AppDomain.DoCallback并查看MarshalByRefObject:您创建一个MarshalByRefObject"调用者",其方法可以执行您想要的操作并在其可变字段中返回一些内容,您创建一个临时AppDomain并调用dom.DoCallback(invoker.DoSomething)来实现此目的对象做你想做的事; 然后你从你的appdomain中的调用者收集结果并卸载临时域.
推荐阅读
赛亚兔备_393
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有