装卸组件 [英] Loading and unloading assemblies

查看:123
本文介绍了装卸组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个win32应用程序,它将.net程序集加载到一个窗口中,允许用户使用它,然后在完成时将其关闭.

问题是,当用户打开.net部件并且即使在用户关闭托管窗口后仍停留在该位置,我的应用程序从大约50mb变为200mb.

我尝试通过.net对象进行处理并手动进行垃圾回收,但是效果不大.我尝试通过ApplicationDomain加载dll,然后卸载它,但这似乎更糟.有点困惑之前,我从未使用过AppDomains.

这是加载代码

I have a win32 application that loads .net assemblies into a window allowing the user to us it and then close it when they finish.

Problem is my application goes from about 50mb to 200mb when the user opens the .net part and stays there even after the user has closed the hosting window.

I tried disposing of by .net objects and manually garbage collecting but this had little effect. I tried loading the dll through an ApplicationDomain and then un loading it but this seemed worse. I have never used AppDomains before an am a little confused.

Here is the loading code

AppDomainSetup setup = AppDomain.CurrentDomain.SetupInformation;
snapInDomain = AppDomain.CreateDomain(snapInName, null, setup);
Assembly a = snapInDomain.Load(snapInAssembly);



这是卸载代码



here is the unload code

AppDomain.Unload(snapInDomain);



我希望这能给我150mb的内存,但它只是增加了更多的内存.问题是:在完成组装后,如何才能使用该组装(加上依赖项),然后卸载该组装并回收内存?

只需添加一些说明即可:

我的win32应用程序通过COM互操作访问托管的.net dll-这个经过管理的.net dll然后根据需要加载插件样式.net dll,问题是它即使在我完成后仍保留插件样式dll占用的内存.

大多数示例似乎都基于控制台样式执行,对于我的问题,使用域似乎要复杂得多,因为要加载的插件是用户控件,需要在另一个域中的表单上托管



I was hopeing this was going to give my 150mb back but it just added more memory. Question is: How can I load an assembly (plus dependencies) use it and then unload it and reclaim the memory when I''m finished with it?

Just to add some clarification:

My win32 App accesses a managed .net dll through COM interop - this manged .net dll then loads plugin style .net dlls as required the problem is it keeps the memory that the plugin style dlls occupy even after i''ve finished with it.

Most examples seem to be based around console style execution, using a domain for my issue seems much more complicated since the plugin which is being loaded is a user control that needs to be hosted on a form in another domain

推荐答案

使用内存探查器来确保至少您正确处置了.NET对象.

^ ]

替代地,您可以尝试一个非常简单的程序集,在该程序集中您将分配200个1 KB的对象,然后释放它们(甚至根本不释放任何对象),然后检查您的编号.

200 MB的丢失"相当大...
Uses a memory profiler to ensure that at least you properly dispose your .NET object.

Memory profiler[^]

Alernatively, you might try a very simple assemblies in which you will allocate 200 objects of 1 KB and then release them (or even no objects at all) and then check your numbers.

200 MB "lost" is quite large...


您需要使用AppDomains,并将有问题的DLL加载到其他应用程序域中.您还(原则上很明显,但是可能很难记住)需要删除对另一个程序集中对象的所有引用以摆脱它.这带来了其他问题,例如您需要跨边界封送事物或使用MarshalByRefObject代理类,但这是使程序集不可加载的唯一方法.

你的问题让我有些困惑.您是否直接尝试将.Net插件加载到非托管进程中?还是在主应用程序中有一个".Net零件",并通过普通的.Net机制加载程序集?我不知道AppDomains如何与非托管进程一起玩.

有一个将插件加载和卸载到我的大厅服务器和客户端中的AppDomain中的示例,它肯定可以正确卸载,因为您可以在卸载DLL时对其进行更新.
You need to use AppDomains, and load the DLL in question into the other app domain. You also (obvious in principle but can be hard to remember) need to drop all references to objects in the other assembly to get rid of it. This carries with it other problems like you need to marshal things across the boundary or use MarshalByRefObject proxy classes, but it''s the only way to make assemblies unloadable.

I am a bit confused by your question. Are you directly trying to load .Net plugins into an unmanaged process? Or do you have a ''.Net part'' which is within the main application, and that loads assemblies via the normal .Net mechanism? I have no idea how AppDomains play with unmanaged processes.

There is an example of loading and unloading plugins into an AppDomain in my lobby server and client, and it definitely unloads correctly because you can update the DLL when it is unloaded.


I''m要尝试这个

http://social.msdn.microsoft.com /Forums/zh-CN/csharplanguage/thread/a6a896ca-8905-41fb-8f52-7f39e89c9a91/ [
I''m going to try this

http://social.msdn.microsoft.com/Forums/en-US/csharplanguage/thread/a6a896ca-8905-41fb-8f52-7f39e89c9a91/[^]

Most examples seem to be around console style execution, using a domain for my issue seems much more complicated since the plugin which is being loaded is a user control that needs to be hosted on a form in another domain

Thanks to everyone for their contribution. The biggest problem I had was understanding domains, as it turns out I would need to redesign our plugin mechanism significantly to put my plugins in their own domains. The interface between the host and the plugin is a usercontrol/embedded in a VB6 form as an activeX so is not easy to separate out. However I managed to fix a significant memory issue as follows:

In the VB6 Form a .net user control is created using:
Set EntryControl = Me.Controls.Add(ctlname, "Entry")



在卸载表单中,通过将entrycontrol设置为none来调用发行版:



In the form unload the release is called by setting entrycontrol to nothing:

Set EntryControl = Nothing



问题是我还对EntryControl的接口有一些参考,一旦将这些接口设置为空,就会释放com接口,并且会发生垃圾回收.



The problem was I also had some reference to interfaces of EntryControl, once these where set to nothing the com interface is released and garbage collection can occur

Set iEntryControlInterface1 = Nothing
Set iEntryControlInterface2 = Nothing
Set EntryControl = Nothing


这篇关于装卸组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆