У меня есть этот код:
По сути, я пытаюсь продемонстрировать использование финализатора С# и создать объект, который не может умереть, я назвал это Зомби. Обычно эта демонстрация отлично работает, но сегодня я попытался использовать тот же код с инициализатором объекта вместо того, чтобы просто присваивать его свойству (в данном случае Name). Я заметил, что есть разница. А именно, что финализатор никогда не вызывается, даже когда я изо всех сил стараюсь заставить сборщик мусора выполнять свою работу.
Может ли кто-нибудь объяснить разницу, или я нашел ошибку в компиляторе C#?
(Я использую C# 4 в VS2010 SP1 на Win7x64)
Спасибо.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace Zombie
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Main thread: " + Thread.CurrentThread.ManagedThreadId);
// case 1: this is where the problem is located.
Zombie z = new Zombie { Name = "Guy" }; // object initializer syntax makes that the finalizer is not called.
// case 2: this is not causing a problem. The finalizer gets called.
//Zombie z = new Zombie();
//z.Name = "Guy";
WeakReference weakZombieGuyRef = new WeakReference(z, true);
z = null;
GC.GetTotalMemory(forceFullCollection: true);
GC.Collect();
while (true)
{
Console.ReadKey();
if (weakZombieGuyRef.IsAlive)
{
Console.WriteLine("zombie guy still alive");
}
else
{
Console.WriteLine("Zombie guy died.. silver bullet anyone?");
}
Zombie.Instance = null;
GC.AddMemoryPressure(12400000);
GC.GetTotalMemory(forceFullCollection: true);
GC.Collect();
}
}
}
public class Zombie
{
public string Name { get; set; }
public static Zombie Instance = null;
~Zombie()
{
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
Console.WriteLine("Finalizer called on zombie" + this.Name);
lock (typeof(Zombie))
{
Instance = this;
GC.ReRegisterForFinalize(this);
}
}
}
}