c# - C# 中的 WeakReference - 操作实例是如何丢失的?

标签 c#

我在 vs2015 中尝试使用弱引用,这是一个我不明白为什么我最后创建的 Action 实例的弱引用完全丢失的示例?

你们能帮我解决这个问题吗?

这是代码和 Invoke 方法未调用,因为该操作在该点具有空值。但它不应该有空值。

class Program
{
    static void Main(string[] args)
    {
        Class2 c1 = new Class2();
        Class4 c4 = new Class4();
        Class3 c3 = new Class3();
        c4.AssignActionA(c3, c4.CreateAction(c1));
        c4.AssignActionB(c3, c4.CreateAction(c1));
        GC.Collect();

        Class5 c5 = new Class5();
        c5.CallActionA(c3);
        c5.CallActionB(c3);

        //Task.Run(() =>
        //{
        //    Class5 c5 = new Class5();
        //    c5.CallAction(c3);      
        //});

        Console.ReadLine();
    }
}

public class Class5
{
    public void CallActionA(Class3 c3)
    {
        Action a;
        c3.A.TryGetTarget(out a);
        a?.Invoke();
    }

    public void CallActionB(Class3 c3)
    {
        c3.B();
    }
}

public class Class4
{
    public Action CreateAction(Class2 c1)
    {
        //Class1 c1 = new Class1();
        Action a = () =>
        {
            var temp = c1;
        };

        return a;
    }

    public void AssignActionA(Class3 c3, Action a)
    {
        c3.A = new WeakReference<Action>(a);
    }

    public void AssignActionB(Class3 c3, Action b)
    {
        c3.B = b;
    }
}

public class Class2
{
}

public class Class3
{
    public WeakReference<Action> A { get; set; }
    public Action B { get; set; }
}

最佳答案

GC 使用根启动垃圾收集的标记 阶段。在您的示例代码中,唯一重要的根源是收集开始时正在执行的方法的局部变量。没有其他静态字段或类似的东西。从那里 WeakReference 是可以到达 Action 的唯一途径。因为它符合收集条件(这是 WeakReference 的全部要点):

Represents a weak reference, which references an object while still allowing that object to be reclaimed by garbage collection.

当你强制垃圾回收时,它会被回收,你不能再调用 I。

关于c# - C# 中的 WeakReference - 操作实例是如何丢失的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41364210/

相关文章:

c# - DataGridView C# 搜索给出 null

c# - 使用 UI 自动化获取 ComboBox 中的项目时出现奇怪的结果

c# - 在 Rider 和 Visual Studio 中使用 C# 和 ASP.Net 的 Git 问题

c# - 文档注释(子类)

c# - 值对象是否应该持有对实体的引用?

c# - 具有相同对象名称的两个命名空间

c# - 高效判断类型

c# - WinForms 中的 header 控件 - 有这样的东西吗?

c# - Unity3d如何检测android上的点击?

c# - 使用 foreach 遍历 DataTableReader 中的行