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

发布于 2024-09-28 00:11:48 字数 297 浏览 2 评论 0原文

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

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

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

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

Is there a way to release an object that was accessed using late-binding (i.e. created by the Activator.CreateInstance() method)?

I have an application that transforms files from one format to another. The assemblies that perform these translations live in a folder in my application directory.

When the application first starts up, I can delete these assemblies from the translation folder without any errors. However, once I process a document through the application (and have bound to one of the translation assemblies using late-binding), I can no longer delete the translation assemblies. At this point, I'm receiving an error message stating that the file is "in use by another application".

Is there a way to "release" the late-bound object in my application once I'm finished using it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

帅的被狗咬 2024-10-05 00:11:48

一旦程序集被加载到应用程序域中,它将一直保留到应用程序域关闭为止。

为了解决这个问题,请将程序集加载到它自己的应用程序域中,例如:

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);

Once an assembly is loaded into an application domain it'll remain until the app domain shuts down.

To get around this load the assembly into it's own application domain, for example:

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);

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

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

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

由于管理辅助 AppDomain 的生命周期可能很痛苦,作为替代方案,如果您使用 ASP .NET 并希望加载许多动态程序集,则可以通过绑定到 < code>AppDomain.CurrentDomain.AssemblyLoaded 事件并保持计数,然后请求托管环境在当前 AppDomain 达到临界数字(例如 500)时回收它,如下所示:

HostingEnvironment.InitiateShutdown();

Once an assembly is loaded into the executing AppDomain, it cannot be unloaded (regardless of whether it is creating via reflection with Activator.CreateInstance).

The recommended approach here is to implement a secondary AppDomain with a lifetime that can unload when it wants to dispose the assemblies.

There are tons of examples, but here is one:
http://www.dotnet247.com/247reference/msgs/28/142174.aspx.

Since managing the lifetime of secondary AppDomains can be a pain, as an alternative, if you are using ASP .NET and are looking to load many dynamic assemblies, you can check when your current AppDomain becomes saturated with dynamically loaded assemblies by binding to the AppDomain.CurrentDomain.AssemblyLoaded event and keeping count, then requesting the hosting environment recycle the current AppDomain when it hits a critical number (say 500) like:

HostingEnvironment.InitiateShutdown();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文