我正在尝试使用垃圾收集器,并且在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次单击)。再次重复此操作。

我看到了iCntiCnt Objs[1000]的删除对象。然后调用GC.Collect(),它使iCnt的计数
谁能解释我这种行为。提前致谢。

最佳答案

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

10-08 13:18