Middle
Kuo skiriasi Dispose ir Finalize metodai?
sobes.tech AI
Atsakymas iš AI
Dispose kviečiamas aiškiai kūrėjo arba vykdymo aplinkos (pvz., using) tam, kad būtų atlaisvinti nevaldomi ištekliai. Finalize (per destruktorių C#) kviečiamas šiukšlių surinkėjo, kai objektas sunaikinamas, jei jis nebuvo aiškiai atlaisvintas.
| Kriterijus | Dispose | Finalize (per destruktorių) |
|---|---|---|
| Kvietimas | Aiškiai nurodytas kūrėjo (using, Dispose()) |
Automatiškai kviečiamas šiukšlių surinkėjo |
| Vykdymo laikas | Determinuotas | Neterminuotas (priklauso nuo šiukšlių surinkėjo) |
| Paskirtis | Atlaisvinti tiek valdomus, tiek nevaldomus išteklius | Tik nevaldomų išteklių atlaisvinimas |
| Įgyvendinimas | IDisposable sąsaja |
Object.Finalize metodo perrašymas (per destruktoriaus sintaksę) |
| Naudojimas | Pirmenybė teikiama išteklių atlaisvinimo būdui | Atsarginis mechanizmas nevaldomiems ištekliams atlaisvinti |
Pavyzdys naudojant using (automatinis Dispose kvietimas):
// Pavyzdys naudojant `IDisposable` įgyvendinančią klasę
using (var fileStream = new System.IO.FileStream("myfile.txt", System.IO.FileMode.Open))
{
// Darbas su failu
} // Čia automatiškai kviečiamas fileStream.Dispose()
Klasės su IDisposable ir destruktoriumi pavyzdys:
using System;
public class MyDisposableClass : IDisposable
{
private IntPtr unmanagedResource; // Atstovauja nevaldomą išteklių
private bool disposed = false;
public MyDisposableClass()
{
// Nevaldomo ištekliaus inicijavimas
unmanagedResource = System.Runtime.InteropServices.Marshal.AllocHGlobal(100);
Console.WriteLine("Išteklis paskirtas.");
}
// `IDisposable` įgyvendinimas
public void Dispose()
{
Dispose(true);
// Slopinti finalizaciją, nes išteklius jau atlaisvintas
GC.SuppressFinalize(this);
Console.WriteLine("Dispose() kviečiamas.");
}
// Apsaugotas virtualus metodas išteklių atlaisvinimui
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
// Valdomų išteklių atlaisvinimas (jei yra)
Console.WriteLine("Valdomų išteklių atlaisvinimas.");
}
// Nevaldomų išteklių atlaisvinimas
if (unmanagedResource != IntPtr.Zero)
{
System.Runtime.InteropServices.Marshal.FreeHGlobal(unmanagedResource);
unmanagedResource = IntPtr.Zero;
Console.WriteLine("Nevaldomas išteklius atlaisvintas.");
}
disposed = true;
}
}
// Destruktorius (finiatorius)
~MyDisposableClass()
{
Dispose(false); // Atlaisvinti tik nevaldomus išteklius
Console.WriteLine("Finiatorius kviečiamas.");
}
}
Dispose metodas turi būti įgyvendintas visuose klasėse, valdančiose nevaldomus išteklius (failus, tinklo ryšius, deskriptorius ir kt.). Finalize turėtų būti naudojamas kaip atsarginis būdas atlaisvinti nevaldomus išteklius, jei Dispose nebuvo iškviestas. Klasės, įgyvendinančios Finalize, turi jį slopinti Dispose(true) metu, kad išvengtų dvigubo išteklių atlaisvinimo.