[英](How) can I make weak references to proxy objects act like weak references to the proxied objects?
作为某些IPC框架的一部分,服务器端代码实现了整数到对象的映射(这样IPC消息可以使用整数来引用对象)。
映射不直接将引用存储到对象,而是存储到IGUIObject
实现,这是一个由包装实际对象的代理对象实现的接口。 也就是说有一个界面
interface IGUIObject
{
Rectangle Bounds { get; }
}
然后是可能的实现
class WindowsFormsControl : IGUIObject
{
private Control m_control;
public WindowsFormsControl( Control control )
{
m_control = control;
}
public virtual Rectangle Bounds
{
get
{
return m_control.Bounds;
}
}
}
映射类是一个单例,如下所示:
class ObjectDict
{
private static readonly ObjectDict s_instance = new ObjectDict();
private Dictionary<int, IGUIObject> m_idToObjectDict;
private Dictionary<IGUIObject, int> m_objectToIdDict;
private int m_lastObjectId;
public static ObjectDict Instance
{
get
{
return s_instance;
}
}
[MethodImpl(MethodImplOptions.Synchronized)]
public IGUIObject objectForId( int id )
{
IGUIObject go;
if ( m_idToObjectDict.TryGetValue( id, out go ) ) {
return go;
}
return null;
}
[MethodImpl(MethodImplOptions.Synchronized)]
public int idForObject( IGUIObject go )
{
// Lookup ID for objects, register object and return new ID if needed
}
// ...
}
这个问题是ObjectDict
类不应该保持应用程序对象不被垃圾收集,即它应该保存弱引用,在这种情况下, ObjectDict.objectForId
应该抛出异常。
唉,
保持对IGUIObject
实现的弱引用似乎没有帮助,因为ObjectDict
类是包装器对象的所有者。 没有其他地方存储它们。 如果IPC系统收到明确的“具有ID 12345的发布对象”消息,则仅从字典中删除包装器对象。 我需要解决的问题是代理对象可能是垃圾收集的,我想要优雅地允许,检测和处理它。 包装器对象应该与代理对象一样长(可能更长),但不能更短。
使WindowsFormsExtension
保持对Control
对象的弱引用,然后使ObjectCache
保持对IGUIObject
实现的弱引用也没有帮助,因为代理对象(即WindowsFormsControl
)不镜像包含对象的“null-ness” 。 另一个复杂因素是IGUIObject
接口有很多(几十个)实现,但只有一个ObjectDict
类。 因此,任何不需要我执行调整所有IGUIObject
实现以开始使用弱引用的繁琐且容易出错的工作的IGUIObject
方案将是更优选的。
有没有人知道如何调整代码,使得ObjectDict
不会(间接地)对IGUIObject
实现包装的任何对象持有强引用?
也许你可以添加另一层抽象:)
class WeakGUIObject : IGUIObject
{
WeakReference wr;
public WindowsFormsControl( IGUIObject inner )
{
wr = new WR(inner);
}
public virtual Rectangle Bounds
{
get
{
var inner = wr.Target;
if (inner == null) throw ObjectDisposedException();
return inner.Bounds;
}
}
}
现在,您可以进行字典引用并WeakGUIObject
实例。 这会自动使所有代理对象变弱。
不确定这整个设计是个好主意。 ObjectDict
客户端可能会发现他们的对象随机消失并开始投掷。 但这似乎是你的目标。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.