WeakReference, WeakEvents:用于动态加载/卸载服务器模块,dll

本文关键字:卸载 服务器 dll 模块 动态 WeakEvents 用于 WeakReference 加载 | 更新日期: 2023-09-27 18:15:52

我在想WeakReferences和WeakEvents是否适用于服务器模块接口的情况。这是一个好的设计吗?

但也有性能问题,当然需要在WeakEvent模式中调用和访问WeakReference,也许太

更新:细节服务器:

  • 有模块管理器,
  • 可以通过共享接口IModule加载/卸载DLL的实现类
  • 模块管理器创建并保存IModule的实例,

模块:

  • 有名称或唯一代码,
  • 需要与其他模块交互,使用他们的方法,属性,事件,

问题是,当一个模块获得另一个模块的实例时(通过名称提供,例如从模块管理器),那么从那时起,就不能保证该模块可以在卸载之前被垃圾收集。

但是可能存在一个给定IModule实现的泛型类(WeakRefModule where T: IModule),约束为IModule,它可以在IModule内部存储WeakReference。然后给定的模块将通过基于WeakRefModule的扩展方法或继承来公开其公共方法。将模块的实例隐藏在WeakReference后面。属性和事件(WeakEvents)也是一样。

这样的模块总是保证其他模块不能阻止它被垃圾回收。

所以问题是,它在多大程度上是一个好的设计,是否有一些隐藏的问题?

WeakReference, WeakEvents:用于动态加载/卸载服务器模块,dll

这个设计基本上是有效的。您需要确保对希望保持加载的模块有一个强引用。否则,GC将不确定地杀死弱引用。

一个问题是模块不能依赖其他存在的模块。如果一个模块被卸载并且弱ref变为null,对该模块的调用将失败或什么都不做。此外,ref变为null的时间点是不确定的。

我不会在这里使用弱引用。你可以创建一个包装器IModule,它只委托给另一个IModule。然后,当你想卸载一个模块时,你可以清除这个包装器。

class WrappedModule : IModule {
 IModule inner;
 public void Dispose() { inner = null; }
 void IModule.SomeMeth() {
  if (inner == null) throw ...;
  else inner.SomeMeth();
 }
}

现在您可能会泄漏包装器对象,但它很小。你不会领导真正的模块。

模块永远不能直接访问其他模块。相反,它们被传递给这个"句柄"类。此句柄可随时禁用