【问题标题】:Are there Weak References in .NET?.NET 中是否存在弱引用?
【发布时间】:2008-12-06 22:13:49
【问题描述】:

我想在我的应用程序中保留一个特定类别对象的列表。但我仍然希望对象被垃圾收集。您可以在 .NET 中创建弱引用吗?

供参考:

来自 MSDN 的回答:

建立一个弱引用 对象,你创建一个 WeakReference 使用对象的实例 跟踪。然后设置目标 属性到该对象并设置 反对为空。对于代码示例, 在类中查看 WeakReference 图书馆。

【问题讨论】:

    标签: c# .net garbage-collection weak-references


    【解决方案1】:

    是的,有一个通用的弱引用类。

    MSDN > Weak Reference

    【讨论】:

      【解决方案2】:

      你能在 .NET 中创建弱引用吗?

      是的:

      WeakReference r = new WeakReference(obj);
      

      使用System.WeakReference

      【讨论】:

        【解决方案3】:

        是的……

        这里有一个很好的例子:

        http://web.archive.org/web/20080212232542/http://www.robherbst.com/blog/2006/08/21/c-weakreference-example/

        在您的类中,您创建了两个成员变量:

        WeakReference _weakRef = null;
        
        Person _strongRef = null;
        

        您创建了两个新的 Person 对象(这是我刚刚为本示例创建的简单对象,由 Name 属性和一些参考跟踪代码组成)。接下来,将成员变量设置为 Person 对象的新创建实例。

        _strongRef = p;
        
        _weakRef = new WeakReference(p1);
        

        这里的区别你会注意到_strongRef 只是一个常规的普通引用,而_weakRef 设置为WeakReference 对象,而person 对象(p1) 作为构造函数中的参数传入。

        如果要进行垃圾收集,或者只是为了测试目的,您自己调用了它:

        GC.Collect();
        

        那么_weakRef成员变量持有的p1目标对象应该被垃圾回收。你可以写代码来检查:

        if (_weakRef.IsAlive)
        

        如果WeakReference 仍然存在,您可以使用如下代码将WeakReference 转换为强引用或普通引用:

        Person p = _weakRef.Target as Person;
        

        现在p 引用被视为强引用,在不再使用之前不会被收集。如果您想在范围之后保留引用,可以将其设置为成员变量。

        【讨论】:

        • 更新为引用回程机器副本。
        【解决方案4】:

        这是WeakReference的完整(非线程安全)实现示例

        ClassA objA = new ClassA();
        WeakReference wr = new WeakReference(objA);
        // do stuff 
        GC.Collect();
        ClassA objA2;
        if (wr.IsAlive)
            objA2 = wr.Target as ClassA; 
        else
            objA2 = new ClassA(); // create it directly if required
        

        WeakReference 位于 System 命名空间中,因此无需为其包含任何特殊程序集。

        【讨论】:

        • 这包含一个竞争条件,不是吗?如果在if (wr.IsAlive)objA2 = wr.Target as ClassA; 之间对象被收集怎么办? wr.Target(因此objA2)将为空。
        • 对象被垃圾回收后,Target 属性可能为 null。 MSDN 文档声明使用 IsAlive 会受到竞争条件的影响,但没有明确说明如何解决问题。 msdn.microsoft.com/en-us/library/…
        • @avl_sweden:如果想对弱引用的目标做任何事情,应该检索目标,然后检查它是否为空。如果它不为空,则至少只要持有新检索到的对它的引用,就保证被引用的对象存在。 IsAlive 属性适用于仅对已死引用感兴趣的代码;这样的代码可以检查Target是否为空,但这可能会导致对象不必要地保持活动状态。
        猜你喜欢
        • 2010-11-08
        • 2010-09-20
        • 1970-01-01
        • 2020-02-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-12
        • 1970-01-01
        相关资源
        最近更新 更多