Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么这个弱参考测试失败了?_C#_Weak References - Fatal编程技术网

C# 为什么这个弱参考测试失败了?

C# 为什么这个弱参考测试失败了?,c#,weak-references,C#,Weak References,为了探索弱引用,我编写了下面的测试来验证我的理解,但测试失败了 据我所知,除了WeakReference实例创建的对象之外,在第一行中没有对新对象的引用,我不禁要问,为什么weakRef认为它的目标仍然存在 我错过了什么?为什么测试失败,还有什么仍然在维护对对象的引用 我可以用一个正常的程序复制你的结果,而不是在mstest中运行它 如果在未优化的构建中运行以下命令,它将打印:Alive:true private static void Main() { Weak

为了探索弱引用,我编写了下面的测试来验证我的理解,但测试失败了

据我所知,除了WeakReference实例创建的对象之外,在第一行中没有对新对象的引用,我不禁要问,为什么weakRef认为它的目标仍然存在

我错过了什么?为什么测试失败,还有什么仍然在维护对对象的引用


我可以用一个正常的程序复制你的结果,而不是在mstest中运行它

如果在未优化的构建中运行以下命令,它将打印:Alive:true

    private static void Main()
    {
        WeakReference weakRef = new WeakReference( new object(), false );

        GC.Collect( GC.MaxGeneration, GCCollectionMode.Forced, true, true );
        GC.WaitForPendingFinalizers();

        // Prints true in debug, false in release.
        Console.WriteLine( "Alive: " + weakRef.IsAlive );
    }
如果我在启用优化的情况下编译,它反而会工作,并以活动方式打印:false

此外,如果我将WeakReference的初始化提取到一个单独的方法,则无论优化如何,它都会工作:

    private static void Main()
    {
        WeakReference weakRef = Init();

        GC.Collect( GC.MaxGeneration, GCCollectionMode.Forced, true, true );
        GC.WaitForPendingFinalizers();

        // Always prints false.
        Console.WriteLine( "Alive: " + weakRef.IsAlive );
    }

    private static WeakReference Init()
    {
        return new WeakReference( new object(), false );
    }

老实说,我不确定原因。我的一个假设是,由于缺乏优化,临时对象被存储在堆栈上的一个隐藏临时变量中。但是,这没有意义,因为GC能够检查堆栈以确定对任何变量的最后一次引用是在什么时候进行的——GC可以收集当前正在运行的函数中的内容,只要它不再被使用。

我可以使用不在mstest中运行的普通程序复制您的结果

如果在未优化的构建中运行以下命令,它将打印:Alive:true

    private static void Main()
    {
        WeakReference weakRef = new WeakReference( new object(), false );

        GC.Collect( GC.MaxGeneration, GCCollectionMode.Forced, true, true );
        GC.WaitForPendingFinalizers();

        // Prints true in debug, false in release.
        Console.WriteLine( "Alive: " + weakRef.IsAlive );
    }
如果我在启用优化的情况下编译,它反而会工作,并以活动方式打印:false

此外,如果我将WeakReference的初始化提取到一个单独的方法,则无论优化如何,它都会工作:

    private static void Main()
    {
        WeakReference weakRef = Init();

        GC.Collect( GC.MaxGeneration, GCCollectionMode.Forced, true, true );
        GC.WaitForPendingFinalizers();

        // Always prints false.
        Console.WriteLine( "Alive: " + weakRef.IsAlive );
    }

    private static WeakReference Init()
    {
        return new WeakReference( new object(), false );
    }

老实说,我不确定原因。我的一个假设是,由于缺乏优化,临时对象被存储在堆栈上的一个隐藏临时变量中。然而,这是没有意义的,因为GC能够检查堆栈以确定何时对任何变量进行了最后一次引用—GC可以收集当前正在运行的函数中的内容,只要它不再被使用。

@JohanP—这是不对的;没有对新对象返回的对象的强引用。是调试还是发布生成?调试器已连接?在任何情况下,首先从其自己的专用方法返回WeakRef,并在调用者中完成GC,可能会获得更好的成功。这确保了没有任何诡计,因为一旦方法返回,只有WeakRef在外部可见。此外,这些天没有“立即收集”的标志吗?@JohanP-weakref不算是一个有力的参考。。。这就是重点。。这是一个弱引用。@JohanP弱引用的要点是它不会导致包含对象的强引用。因此,包含的对象可能符合回收条件。测试在调试模式和发布模式下都失败,如果我从静态方法返回新对象,则没有区别-测试仍然失败。@JohanP-这不对;没有对新对象返回的对象的强引用。是调试还是发布生成?调试器已连接?在任何情况下,首先从其自己的专用方法返回WeakRef,并在调用者中完成GC,可能会获得更好的成功。这确保了没有任何诡计,因为一旦方法返回,只有WeakRef在外部可见。此外,这些天没有“立即收集”的标志吗?@JohanP-weakref不算是一个有力的参考。。。这就是重点。。这是一个弱引用。@JohanP弱引用的要点是它不会导致包含对象的强引用。因此,包含的对象可能符合回收的条件。测试在调试和发布模式下都失败,如果我从静态方法返回新对象,这没有什么区别-测试仍然失败。谢谢,我很高兴我没有发疯。优化似乎确实解决了这个问题,但是从静态方法返回我需要的实际对象的技巧对我不起作用。这是我实际运行的测试的一个精心设计的简化版本。谢谢你的见解,非常感谢谢谢,我很高兴我没有发疯。优化似乎确实解决了这个问题,但是从静态方法返回我需要的实际对象的技巧对我不起作用。这是我实际运行的测试的一个精心设计的简化版本。谢谢你的见解,非常感谢