gpt4 book ai didi

c# - 垃圾收集运行时如何调用析构函数 [.NET]?

转载 作者:太空宇宙 更新时间:2023-11-03 20:30:03 25 4
gpt4 key购买 nike

我正在试验垃圾收集器并在 destructor 调用中发现奇怪的计数 iCnt。这是代码:-

public class MyClass
{
static long iCnt;
public MyClass()
{
iCnt++;
}

~MyClass()
{
iCnt--;
}
static public string ObjectCount
{
get
{
return iCnt.ToString();
}
}
}

下面的代码是创建对象,删除对象(通过分配给null来取消引用)并显式调用GC.Collect()。我将所有这些都放在一个 Win Form 中,它的 Timerinterval = 100,计时器显示 iCnt 的当前计数。

public partial class Form1 : Form
{
MyClass[] Objs;
public Form1()
{
InitializeComponent();
}

private void btnCreateObjects_Click(object sender, EventArgs e)
{
Objs = new MyClass[1000];
for (int i = 0; i < 1000; i++)
{
Objs[i] = new MyClass();
}
}

private void timer1_Tick(object sender, EventArgs e)
{
label2.Text = MyClass.ObjectCount;
}
private void btnDeleteObjects_Click(object sender, EventArgs e)
{
for (int i = 0; i < 1000; i++)
{
Objs[i] = null;
}
}

private void btnInvokeGC_Click(object sender, EventArgs e)
{
GC.Collect();
}
}

现在创建对象,直到自动调用垃圾收集器(对我来说,它需要 24 次点击)。再次重复这个 Action 。

我看到这个 iCnt < 1000. 这让我很困惑在这种情况下析构函数是如何调用的。当iCnt < 1000 时,点击删除引用Objs[1000] 的对象。然后调用 GC.Collect() 计算 iCnt < 0(很奇怪)。

任何人都可以向我解释这种行为。提前致谢。

最佳答案

这是一个非常经典的线程错误。析构函数在终结器线程上运行,与递增计数的线程异步运行。您需要使用 Interlocked.Increment() 和 Decrement() 来安全地执行此操作。或者使用 lock 关键字。

关于c# - 垃圾收集运行时如何调用析构函数 [.NET]?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7939456/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com