简体   繁体   English

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

[英](How) can I make weak references to proxy objects act like weak references to the proxied objects?

As part of some IPC framework, the server-side code implements a mapping of integers to objects (such that IPC messages can use integers to reference objects). 作为某些IPC框架的一部分,服务器端代码实现了整数到对象的映射(这样IPC消息可以使用整数来引用对象)。

The mapping doesn't store references straight to the objects though but to IGUIObject implementations, an interface to be implemented by proxy objects which wrap the actual objects. 映射不直接将引用存储到对象,而是存储到IGUIObject实现,这是一个由包装实际对象的代理对象实现的接口。 Ie there's an interface like 也就是说有一个界面

interface IGUIObject
{
    Rectangle Bounds { get; }
}

and then possible implementations like 然后是可能的实现

class WindowsFormsControl : IGUIObject
{
    private Control m_control;

    public WindowsFormsControl( Control control )
    {
        m_control = control;
    }

    public virtual Rectangle Bounds
    {
        get
        {
            return m_control.Bounds;
        }
    }
}

The mapping class, a singleton, looks like this: 映射类是一个单例,如下所示:

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
    }

    // ...
}

The problem with this is that the ObjectDict class should not keep the application objects from being garbage collected, ie it should hold weak references and in such cases ObjectDict.objectForId should throw an exception. 这个问题是ObjectDict类不应该保持应用程序对象不被垃圾收集,即它应该保存弱引用,在这种情况下, ObjectDict.objectForId应该抛出异常。

Alas, 唉,

  • holding weak references on the IGUIObject implementations doesn't seem to help, because the ObjectDict class is the owner of the wrapper objects. 保持对IGUIObject实现的弱引用似乎没有帮助,因为ObjectDict包装器对象的所有者。 There's no other place where they are stored. 没有其他地方存储它们。 The wrapper objects only get removed from the dictionaries if the IPC system receives an explicit 'release object with ID 12345' message. 如果IPC系统收到明确的“具有ID 12345的发布对象”消息,则仅从字典中删除包装器对象。 The issue I need to solve though is that it may be that the proxied object is garbage collected and I want to allow, detect and handle it gracefully. 我需要解决的问题是代理对象可能是垃圾收集的,我想要优雅地允许,检测和处理它。 The wrapper objects should live as long as the proxied objects (potentially longer), but no shorter. 包装器对象应该与代理对象一样长(可能更长),但不能更短。

  • making WindowsFormsExtension hold a weak reference to the Control object and then making ObjectCache hold a weak reference to the IGUIObject implementation doesn't help either, because the proxy object (ie WindowsFormsControl ) doesn't mirror the "null-ness" of the contained object. 使WindowsFormsExtension保持对Control对象的弱引用,然后使ObjectCache保持对IGUIObject实现的弱引用也没有帮助,因为代理对象(即WindowsFormsControl )不镜像包含对象的“null-ness” 。 Another complicating factor is that there are many (a couple dozen) implementations of the IGUIObject interface, but only a single ObjectDict class. 另一个复杂因素是IGUIObject接口有很多(几十个)实现,但只有一个ObjectDict类。 So any solution which does not require me to do the tedious and error-prone job of adjusting all IGUIObject implementations to start using weak references would be much preferred. 因此,任何不需要我执行调整所有IGUIObject实现以开始使用弱引用的繁琐且容易出错的工作的IGUIObject方案将是更优选的。

Does anybody know how to adjust the code such that ObjectDict does not (indirectly) hold strong references on any objects wrapped by IGUIObject implementations? 有没有人知道如何调整代码,使得ObjectDict不会(间接地)对IGUIObject实现包装的任何对象持有强引用?

Maybe you can add another layer of abstraction :) 也许你可以添加另一层抽象:)

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

Now you can make the dictionary reference and hand out WeakGUIObject instances. 现在,您可以进行字典引用并WeakGUIObject实例。 This automatically makes all proxied objects weak. 这会自动使所有代理对象变弱。

Not sure this whole design is a good idea. 不确定这整个设计是个好主意。 Clients of ObjectDict might find that their objects disappear at random times and start throwing. ObjectDict客户端可能会发现他们的对象随机消失并开始投掷。 But that seems to be what you are aiming at. 但这似乎是你的目标。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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