简体   繁体   English

应用程序使用的 DLL 的热卸载/重新加载

[英]Hot Unload/Reload of a DLL used by an Application

I have an application that loads a DLL to execute a specific part of processing我有一个应用程序加载一个 DLL 来执行处理的特定部分

Example : "Application.dll" loading "Process.dll" 

Process.dll is dynamically loaded at Runtime , using reflection, and not referenced in the application. Process.dll 在运行时动态加载,使用反射,而不是在应用程序中引用。

After processing is finished, the DLL needs to be recompiled on server and loaded back again later.处理完成后,DLL 需要在服务器上重新编译,稍后再次加载回来。
In order to do so, I need to free it, otherwise I get the following message : "Unable to copy file "Process.dll" to "Process.dll". The process cannot access the file 'Process.dll' because it is being used by another process."为此,我需要释放它,否则我会收到以下消息:“无法将文件“Process.dll”复制到“Process.dll”。进程无法访问文件“Process.dll”,因为它是被另一个进程使用。”

So the question is : How to programmatically free/release/unload the Process.dll from my application before loading it back again.所以问题是:如何在重新加载之前以编程方式从我的应用程序中释放/释放/卸载Process.dll Of course,the whole point is to do this WITHOUT stopping the Application.当然,重点是在停止应用程序的情况下执行此操作。

EDIT 1 :编辑 1:

A proposed solution goes like this :一个提议的解决方案是这样的:

AppDomain newDomain4Process = AppDomain.CreateDomain("newDomain4Process");
Assembly processLibrary = newDomain4Process.Load("Process.dll");
AppDomain.Unload(newDomain4Process);

The problem I am still having is that, though I am giving the proper full path, I get a FileNotFound Exception .我仍然遇到的问题是,虽然我提供了正确的完整路径,但我收到了FileNotFound Exception The answer to this post did not have the expected effect either. 这篇文章的答案也没有达到预期的效果。

EDIT 2 :编辑 2:

This post saved my life, here is the code : 这篇文章救了我的命,这是代码:

class ProxyDomain : MarshalByRefObject
    {
        public Assembly GetAssembly(string AssemblyPath)
        {
            try
            {
                return Assembly.LoadFrom(AssemblyPath);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }

   ProxyDomain pd = new ProxyDomain();
   Assembly a = pd.GetAssembly(FullDLLPath);

EDIT 3 :编辑 3:
I didn't get access to the AppDomain and unload it with the previous solution though.不过,我无法访问 AppDomain 并使用以前的解决方案将其卸载。 When I used the classic method of AppDomain Creation, I felt into Alexei's warning : AppDomain.Unload "seemed" to work, but the assembly was still loaded (Module View).当我使用 AppDomain Creation 的经典方法时,我感受到了 Alexei 的警告: AppDomain.Unload “似乎”工作,但程序集仍然加载(模块视图)。 So I still have my problem in some way, since I can't really unload the DLL efficiently.所以我在某种程度上仍然有我的问题,因为我不能真正有效地卸载 DLL。

It's been quite a while since I looked at this but I'm fairly sure that you'd need to create a new AppDomain and then load the DLL inside there.自从我看这个已经有一段时间了,但我很确定您需要创建一个新的AppDomain ,然后在其中加载 DLL。

The reason is that you can't unload an Assembly by it self but you can unload an AppDomain that contains an Assembly .原因是您不能自行卸载Assembly ,但可以卸载包含AssemblyAppDomain

Once an assembly has been loaded into an AppDomain , it cannot be unloaded.一旦程序集加载到AppDomain ,就无法卸载。 You have to dispose of the AppDomain .您必须处理AppDomain If you need to load and unload assemblies within an application, you'll need to spawn a new AppDomain and load the assembly, then destroy the AppDomain once you're finished with the assembly.如果您需要在应用程序中加载和卸载程序集,则需要生成一个新的AppDomain并加载该程序集,然后在完成该程序集后销毁该AppDomain

While you seem to solve the problem according to your edit here are couple comments:虽然您似乎根据您的编辑解决了问题,但这里有几条评论:

Watch out for objects from your Process.dll "leaking" into main AppDomain.注意 Process.dll 中的对象“泄漏”到主 AppDomain 中。 Ie something like throwing custom exception defined in Process.dll and caught in main AppDomain will force Process.dll to be loaded into main AppDomain.即抛出 Process.dll 中定义并在主 AppDomain 中捕获的自定义异常将强制 Process.dll 加载到主 AppDomain 中。 Check list of loaded assemblies in the main AppDomain after performing operations you are interested in.执行您感兴趣的操作后,检查主 AppDomain 中加载的程序集列表。

Unloading of AppDomain can fail and may take long time.卸载 AppDomain 可能会失败,并且可能需要很长时间。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM