繁体   English   中英

(如何)我可以对代理对象进行弱引用,就像对代理对象的弱引用一样?

[英](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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM