我正在尝试使用垃圾收集器,并且在iCnt
调用中发现了奇怪的计数destructor
。
这是代码:
public class MyClass
{
static long iCnt;
public MyClass()
{
iCnt++;
}
~MyClass()
{
iCnt--;
}
static public string ObjectCount
{
get
{
return iCnt.ToString();
}
}
}
下面的代码用于创建对象,删除对象(通过分配给
null
取消引用)并显式调用GC.Collect()
。我在具有
Timer
interval = 100
的Win窗体中拥有了所有内容,计时器显示了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次单击)。再次重复此操作。
我看到了
iCnt
当iCnt
Objs[1000]的删除对象。然后调用GC.Collect()
,它使iCnt
的计数谁能解释我这种行为。提前致谢。
最佳答案
这是一个非常经典的线程错误。析构函数在终结器线程上运行,与递增计数的线程异步运行。您需要使用Interlocked.Increment()和Decrement()来安全地执行此操作。或使用lock关键字。