开发者

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

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

Process.dll is dynamically loaded at Runtime, using reflection, and not referenced in the application.

After processing is finished, the DLL needs to be recompiled on server and loaded back again later.

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."

So the question is : How to programmatically free/release/unload the Process.dll from my application before loading it back again. Of course,the whole point is to do this WITHOUT stopping the Application.

EDIT 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. The answer to this post did not have the expected effect either.

EDIT 2 :

This pos开发者_如何学Pythont 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 :

I didn't get access to the AppDomain and unload it with the previous solution though. 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). So I still have my problem in some way, since I can't really unload the DLL efficiently.


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.

The reason is that you can't unload an Assembly by it self but you can unload an AppDomain that contains an Assembly.


Once an assembly has been loaded into an AppDomain, it cannot be unloaded. You have to dispose of the 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.


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. I.e. something like throwing custom exception defined in Process.dll and caught in main AppDomain will force Process.dll to be loaded into main AppDomain. Check list of loaded assemblies in the main AppDomain after performing operations you are interested in.

Unloading of AppDomain can fail and may take long time.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜