【问题标题】:Release Late-Bound Object in C#在 C# 中释放后期绑定对象
【发布时间】:2010-10-13 16:15:24
【问题描述】:

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

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

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

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

【问题讨论】:

标签: c# reflection late-binding


【解决方案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);

【讨论】:

    【解决方案2】:

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

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

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

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

    HostingEnvironment.InitiateShutdown();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-25
      • 2012-03-05
      • 2015-04-25
      • 2010-12-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多