C#参考计数

C#参考计数,c#,.net,dictionary,reference,C#,.net,Dictionary,Reference,我正在寻找一种在C#中实现ref计数的好模式。我有一个 Dictionary<string, MyObject> ObjList; 字典对象列表; 我想做的是分发对MyObject实例的引用(如果它们存在),并创建新的引用(如果它们不存在)。我的代码中的多个位置可能引用了MyObject实例,但当所有实例都被释放后,我希望将其从字典中删除。我已经研究了WeakReference,但我不确定它是否适用于这里 编辑1。) 详细信息我正在使用服务器,因此每当我引用某个项目时,我都希望使

我正在寻找一种在C#中实现ref计数的好模式。我有一个

Dictionary<string, MyObject> ObjList;
字典对象列表;
我想做的是分发对
MyObject
实例的引用(如果它们存在),并创建新的引用(如果它们不存在)。我的代码中的多个位置可能引用了
MyObject
实例,但当所有实例都被释放后,我希望将其从字典中删除。我已经研究了
WeakReference
,但我不确定它是否适用于这里

编辑1。)
详细信息我正在使用服务器,因此每当我引用某个项目时,我都希望使用字典查找对该项目的现有引用。当我不再需要该项目时,我想取消订阅该项目。要知道我的代码中何时或有多少地方正在使用该项并不容易。

在这些场景中,我所做的是创建一个字典。
WeakReference
的作用是允许词典引用
MyObject
的实例,而无需将该实例保留在内存中。因此,一旦释放了对该对象的所有其他引用,该项的条目仍将存在于字典中。但是,该条目将引用一个
WeakReference
,其中
IsAlive
false
,而
目标为
null
。如果您愿意,您可以偶尔通过删除
WeakReference
不活动的所有条目来清理字典。

这就是您需要的:

public class WeakReferences<T>
{
    private Func<string, T> _factory;

    public WeakReferences(Func<string, T> factory)
    {
        _factory = factory;
    }

    private Dictionary<string, WeakReference> _references =
        new Dictionary<string, WeakReference>();

    public T this[string index]
    {
        get
        {
            T target = default(T);
            if (_references.ContainsKey(index))
            {
                var wr = _references[index];
                target = (T)wr.Target;
                if (wr.IsAlive)
                {
                    Console.WriteLine("Reused: " + index);
                    return target;
                }
            }
            target = _factory(index);
            _references[index] = new WeakReference(target);
            return target;
        }
    }
}

现在还不清楚你想做什么…我正在做的是使用OPC服务器,所以当一个对象没有引用时,我想取消订阅。我的印象是,我的字典将始终有一个引用,因此它将永远不会被处理
WeakReference
将起作用,但如果您能够明确地处理实例,我只想这么说。需要注意的是,
MyObject
必须使用调用
.Dispose()
的类析构函数正确实现
IDisposable
,否则将不会处理
WeakReference
MyObject
。棘手的部分是如何执行代码清理代码。在上面的示例中,您将如何获得。删除:a。我需要放置代码来告诉Opc服务器我done@MDK-你根本不需要告诉我这个来清理。这都是弱引用-一旦代码中其他地方不再有任何引用,所有这些都将由GC清理。@MDK-如果您要添加的对象需要处理,那么不需要使用
Func工厂
,并允许外部分配实例,以便您可以管理处理所以我猜你是说没有自动的方法来判断对象何时被取消引用。我不想依赖代码的其他用户来显式处理对象。@MDK-必须显式处理对象。垃圾收集器不会自动执行此操作。因此,它不能帮助您检查对象是否被引用。但是,您可以检查
WeakReference
IsAlive
属性,查看它是否已被垃圾收集。但是,这并不能告诉你它是否被处理掉了。我认为您可能需要让我们知道您需要如何管理对象的生命周期,以便我们可以就最佳方式向您提供建议。
    Func<string, object> f = k =>
    {
        Console.WriteLine("Created: " + k);
        return new object();
    };

    var wrs = new WeakReferences<object>(f);

    var a = wrs["a"];
    var b = wrs["b"];
    a = wrs["a"];
    b = wrs["b"];
    a = null;
    GC.Collect();
    a = wrs["a"];
    b = wrs["b"];
Created: a
Created: b
Reused: a
Reused: b
Created: a
Reused: b