在C#中释放后期绑定对象

时间:2010-10-13 16:15:25

标签: c# reflection late-binding

有没有办法释放使用后期绑定(即由Activator.CreateInstance()方法创建)访问的对象?

我有一个应用程序可以将文件从一种格式转换为另一种格式。执行这些转换的程序集位于我的应用程序目录中的文件夹中。

首次启动应用程序时,我可以从翻译文件夹中删除这些程序集而不会出现任何错误。但是,一旦我通过应用程序处理文档(并使用后期绑定绑定到其中一个翻译程序集),我就无法再删除翻译程序集。此时,我收到一条错误消息,指出该文件“正由另一个应用程序使用”。

有没有办法在我完成使用后“释放”应用程序中的后期绑定对象?

2 个答案:

答案 0 :(得分:1)

将程序集加载到应用程序域后,它将一直保留到应用程序域关闭。

要解决此问题,请将程序集加载到自己的应用程序域中,例如:

AppDomain app = AppDomain.CreateDomain("PlugInDomain");
ObjectHandle objectHandle = app.CreateInstanceFrom(assemblyPath, 
             "MyNamespace.MyComponent");
MyComponent component = (MyComponent) objectHandle.Unwrap();

// do stuff

// Now kill app domain, assembly can be overwritten after this.
AppDomain.Unload(app);

答案 1 :(得分:0)

将程序集加载到正在执行的AppDomain中后,无法卸载它(无论是否通过Activator.CreateInstance反射创建)。

这里推荐的方法是实现一个辅助AppDomain,它的生命周期可以在它想要处理程序集时卸载。

有很多例子,但这里有一个例子: http://www.dotnet247.com/247reference/msgs/28/142174.aspx

由于管理辅助AppDomain的生命周期可能会很麻烦,作为替代方案,如果您使用的是ASP .NET并且希望加载许多动态程序集,则可以通过绑定检查当前AppDomain何时被动态加载的程序集所饱和到AppDomain.CurrentDomain.AssemblyLoaded事件并保持计数,然后请求托管环境回收当前AppDomain,当它达到一个关键数字(比如500)时,如:

HostingEnvironment.InitiateShutdown();