GC.WaitForPendingFinalizers无法在异步方法中工作?

马塞尔·W

我有一些单元测试,以验证使用WeakReferences的对象是否正常工作。将这些对象重构为异步工作后,单元测试将失败。这似乎是由于使用异步时GC.WaitForPendingFinalizers无法工作(或工作方式不同?)引起的。

为了检查这一点,我创建了一个简单的WPF应用程序,其中包含两个按钮,一个带有常规Click事件,另一个带有异步Click事件。

当我按下NormalGCTest按钮时,将显示“收集的对象垃圾:真实”。

但是,当我按下AsyncGCTest按钮时,将显示“对象垃圾收集:False”。

到底是怎么回事?有没有办法在我的测试中强制执行完整的垃圾回收?

    private void NormalGCTest(object sender, RoutedEventArgs e)
    {
        var temp1 = new object();
        var temp2 = new WeakReference(temp1);
        temp1 = null;
        GC.Collect();
        GC.WaitForPendingFinalizers();
        temp1 = temp2.Target;
        System.Diagnostics.Debug.WriteLine("object garbage collected: {0}", temp1 == null);
    }

    private async void AsyncGCTest(object sender, RoutedEventArgs e)
    {
        var temp1 = new object();
        var temp2 = new WeakReference(temp1);
        temp1 = null;
        GC.Collect();
        GC.WaitForPendingFinalizers();
        temp1 = temp2.Target;
        System.Diagnostics.Debug.WriteLine("object garbage collected: {0}", temp1 == null);
        await Task.Delay(0);
    }
马克·格雷韦尔

对我来说,它已经可以正常工作-我得到True/ True但是,您可以尝试一些事情来澄清正在发生的事情-例如:

var wr = CreateWeakReference();
Console.WriteLine("object available: {0}", wr.Target != null);
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
GC.WaitForPendingFinalizers();
Console.WriteLine("object garbage collected: {0}", wr.Target == null);

static WeakReference CreateWeakReference()
{
    return new WeakReference(new object());
}

这会使用较少的局部变量,这可能会导致混淆,具体取决于编译器如何转换C#。它还使用了更具侵略性的GC.Collect

但重要的是:停止调用垃圾收集器您几乎永远都不要这样做。最后的想法-您可能要避免async void是的,我知道这是一个事件处理程序,但是有一个不错的技巧是立即调用非async void方法(await必要时使用)。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

GC.WaitForPendingFinalizers无法在异步方法中工作?

来自分类Dev

Java Setter中的GC

来自分类Dev

Go的精确GC如何工作?

来自分类Dev

在Azure Databricks中配置GC

来自分类Dev

无法打印GC详细信息

来自分类Dev

在GC期间无法释放幻影参考

来自分类Dev

Java GC中的压缩是什么?

来自分类Dev

避免在Java CMS GC中升级失败

来自分类Dev

在一段代码中暂停GC

来自分类Dev

G1 GC中的内存分配

来自分类Dev

GC开销可选<T>中爪哇

来自分类Dev

如何在PyPy中调试GC?

来自分类Dev

后台和GC中的无尽线程

来自分类Dev

在新文物中启用GC分析

来自分类Dev

Java中的对象分配和GC行为

来自分类Dev

jmeter中超出了gc内存开销

来自分类Dev

软引用在java中GC的作用

来自分类Dev

dvc gc 和远程缓存中的文件

来自分类Dev

无法访问的char数组未在完整gc中进行gc'ed

来自分类Dev

无法访问的char数组未在完整gc中进行gc'ed

来自分类Dev

如果没有参考变量,java GC如何工作?

来自分类Dev

Angular 1.5,$ interval并允许GC完成它的工作

来自分类Dev

gc.log是异步编写的吗?安全地将gc.log放在NFS挂载上?

来自分类Dev

Ubuntu Linux Git gc说错误:无法运行重新打包

来自分类Dev

无法执行dex:超出了GC开销限制->库

来自分类Dev

python-reload()时无法访问gc

来自分类Dev

使用Epsilon GC时,无法使用Flight Recorder

来自分类Dev

Java SWT GC无法在Canvas上绘制文本

来自分类Dev

无法执行dex:超出了GC开销限制->库