Witam serdecznie,
mam dwa pytania, na które nie mogę znaleźć odpowiedzi.
-
Czy w NET.Core 8.0 funkcjonuje jeszcze destruktor? Czy zamiast tego używa się już tylko Using, powiązanego IDisposable i Dispose()? A jeśli funkcjonuje, to jak go wywołać? Poniższy kod uruchomiony na NET.Framework niszczy obiekt po podstawieniu do niego null i wywołuje wspomniany destruktor. Natomiast po wrzuceniu do NET.Core 8.0 już nie zachowuje się w ten sam sposób, właściwie sygnalizując nawet nie do końca właściwie przypisanie ze względu na to, że obiekt nie został zadeklarowany jako nullable.
class Program { static void Main(string[] args) { Program program = new Program(); program.StartTest(); } private void StartTest() { TestObject testObject = new TestObject(); Console.ReadKey(); testObject = null; } } class TestObject { public TestObject() { Console.WriteLine("I am inside Constructor"); } ~TestObject() { Console.WriteLine("I am inside Destructor"); } } -
I nurtuje mnie jeszcze kwestia żywotności obiektów. Czy to jest coś, czym należy zaprzątać sobie głowę? Czy GC wystarczająco to ogarnie? I skąd wiadomo, który obiekt będzie żył własnym życiem, a który zostanie automatycznie uprzątnięty (jeśli tak się w ogóle dzieje)? Ja mam taką dziwną wizję w głowie, że każde new() utworzy kolejny obiekt, coraz bardziej zajmując pamięć, aż jej zabraknie. Poniżej taki przykład, który na szybko napisałem
W metodzie StartTest() w pierwszej linii tworzę obiekt jako instancję RandomValueWritterWithTimer, która zawiera wewnątrz timer. Po utworzeniu obiektu, timer co 2 sekundy zapisuje wartość losową do pliku txt. I to działa. Rozumiem, że taki obiekt będzie żył i nie zostanie usunięty przez GC.
W kolejnej linijce tworzony jest timer wewnątrz klasy Program, którego wywołanie tworzy nowy obiekt jako instancję klasy RandomValueWritter i wywołując metodę WriteRandomValue() również dokonuje zapisu do pliku txt, ale o innej nazwie.
I teraz pytanie - czy każdy obiekt tworzony co 2 sekundy jako instancja RandomValueWritter zostanie w pamięci? Czy zostanie automatycznie zniszczony przez GC?
Celowo użyłem using w przypadku StreamWrittera, żeby nie zostawić czasem otwartego pliku.
using System.Timers;
class Program
{
static void Main(string[] args)
{
Program program = new Program();
program.StartTest();
}
private void StartTest()
{
RandomValueWritterWithTimer randomValueWritter = new RandomValueWritterWithTimer();
System.Timers.Timer timer = new System.Timers.Timer();
timer.Interval = 2000;
timer.Elapsed += Timer_Elapsed;
timer.Start();
Console.ReadKey();
}
private void Timer_Elapsed(object? sender, ElapsedEventArgs e)
{
RandomValueWritter randomValueWritter = new RandomValueWritter();
randomValueWritter.WriteRandomValue();
}
}
class RandomValueWritter
{
public void WriteRandomValue()
{
using (StreamWriter sw = new StreamWriter(".\\RandomValues.txt", true))
{
Random random = new Random();
sw.WriteLine(random.Next(0, 100));
}
}
}
class RandomValueWritterWithTimer
{
public RandomValueWritterWithTimer()
{
System.Timers.Timer timer = new System.Timers.Timer();
timer.Interval = 2000;
timer.Elapsed += Timer_Elapsed;
timer.Start();
}
private void Timer_Elapsed(object? sender, System.Timers.ElapsedEventArgs e)
{
using (StreamWriter sw = new StreamWriter(".\\RandomValuesWithTimer.txt", true))
{
Random random = new Random();
sw.WriteLine(random.Next(0,100));
}
}
}
I przy okazji, jeśli mógłbym prosić o jakieś wskazówki, co należałoby tutaj zmienić, dorobić, żeby napisany przeze mnie program był jak najbardziej zgodny ze sztuką.
Może gdzieś coś powinno być w innym miejscu, coś może sprawdzone wcześniej zanim obsłużone? Gdzieś może istnieje jakaś luka, która może coś spowodować w jakiejś sytuacji? Każda wskazówka dla mnie na tym etapie na wagę złota.
Wiem, że chyba Random random = new Random(); mógłbym zapisać Random random = new();
Z góry dziękuję