C# IDisposable Nedir? Kullanımı

C# ve .NET içerisindeki dillerde kaynak yönetimi için kullanılan IDisposable arayüzü nedir, kullanımı ve using anahtar kelimesi ile ilgili bilgiler yer alıyor.

C# IDisposable nedir?

C# içerisinde bellek/kaynak yönetimi yapmak için kullanılan bir arayüzdür.

IDisposable arayüz tanımını yaparken kullandığım bellek yönetimi yapmak belki sizi şaşırtmış olabilir.

Çünkü C#, Java ve Python gibi üst seviye olarak adlandırılan dillerde yer alan Garbage Collector yapısı bellek yönetimini bizim yerimize yapmaktadır.

C# bellek yönetimi belirli aralıklarla veya açıkca belirtilerek çalışır.

using System;

class Program {

    static void Main() {

        Sinif s1 = new Sinif();
        Console.WriteLine("Uzun süren bir işlem.");
    }
}

class Sinif {
    public Sinif() {
        Console.WriteLine("Nesne oluşturuldu.");
    }

    ~Sinif() {
        Console.WriteLine("Kullanılan kaynaklar silindi.");
    }
}

Yukarıdaki örneğin çıktısı aşağıdaki gibi olacaktır.

Nesne oluşturuldu.
Uzun süren bir işlem.
Kullanılan kaynaklar silindi.

Burada herşey olağın gibi görünsede s1 nesnesinde yer alan kaynaklar uzun süren bir işlem boyunca kullanılmamasına rağmen bellekte yer işgal edecektir.

Bu durum farklı faaliyet alanı kullanıldığında da devam edecektir.

using System;

class Program {

    static void Main() {

        { //  farklı faaliyet alanı
            Sinif s1 = new Sinif();
        }
        Console.WriteLine("Uzun süren bir işlem.");
    }
}

class Sinif {
    public Sinif() {
        Console.WriteLine("Nesne oluşturuldu.");
    }

    ~Sinif() {
        Console.WriteLine("Kullanılan kaynaklar silindi.");
    }
}

Garbage Collector yapısının bu belleği silmemesinin nedeni belleğin yeterli olması ve s1 ile belirlenen değişkenin bir alanı işaret etmesidir.

Nesne null olarak işaretlense bile Garbage Collector keyfi olarak işlem yapabilir diyebiliriz.

Garbage Collector yapısının çalıştırılması için GC sınıfında yer alan Collect metodu da kullanılabilir.

Ancak sonuç yine değişmeyecektir.

Nesnenin işlemi bitirmesinden sonra kullandığı alanları serbest bırakması için bir metot hazırlanıp her işlem sonrası çalıştırılabilir.

using System;

class Program {

    static void Main() {

        Sinif s1 = new Sinif();
        s1.KullanilanKaynaklariSerbestBirak();
        Console.WriteLine("Uzun süren bir işlem.");
    }
}

class Sinif {
    public Sinif() {
        Console.WriteLine("Nesne oluşturuldu.");
    }

    public void KullanilanKaynaklariSerbestBirak() {
        Console.WriteLine("Kullanılan kaynaklar silindi.");
    }

    ~Sinif() { }
}

Ancak bu etkili bir çözüm olmayacaktır.

Çünkü standart bir kullanımı yoktur ve metodun çalıştırılmasına ihtiyaç vardır.

C# içerisinde bu işlemi bizim için yapan using ifadesi yer alır.

Ancak using ifadesinin kullanımı için sınfın standart olarak belirlenmiş IDisposable arayüzünü uyguluyor olması gerekir.

IDisposable arayüzü uygulayan sınıfların Dispose metoduna sahip olması gerekir.

Yani yukarıda kaynakları serbest bırakmak için yazdığımız metot Dispose olacaktır.

using System;

class Program {

    static void Main() {

        using(Sinif s1 = new Sinif()) {
            Console.WriteLine("s1 ile ilgili işlemler burada yapılabilir.");
        }
        Console.WriteLine("Uzun süren bir işlem.");
    }
}

class Sinif : IDisposable {
    public Sinif() {
        Console.WriteLine("Nesne oluşturuldu.");
    }

    public void Dispose() {
        Console.WriteLine("Kullanılan kaynaklar silindi.");
    }

    ~Sinif() { }
}

Artık s1 nesnesi ile ilgili işlemimiz bittiğinde using sayesinde otomatik olarak Dispose metodu çalıştırılacaktır.

Bu metot içerisinde kullanılan kaynaklar silinmek için kullanılabilir.

Kaynak kaynak diyoruz ne bu kaynak derseniz.

Dosya okumak için kullanılan FileStream örneği aşağıda yer almaktadır.

using System;
using System.IO;

class Program {

    static void Main() {

        Sinif s1 = new Sinif("birdosya.txt");
        Console.WriteLine("Uzun süren bir işlem.");
    }
}

class Sinif {

    private FileStream DosyaIslemleri = null;

    public Sinif(string dosyaYolu) {
        DosyaIslemleri = new FileStream(dosyaYolu, FileMode.OpenOrCreate);
    }

    ~Sinif() {
        Console.WriteLine("Kullanılan kaynaklar silindi.");
        DosyaIslemleri.Close();
        DosyaIslemleri = null;
    }
}

Örnekteki sınıf kurucu metodu FileStream ile dosya kaynağını açmıştır ve kaynağın kapatılması yıkıcı metot içerisinde yapılmıştır.

Ancak C# içerisinde yer alan Garbage Collector yapısının yıkıcı metodu ne zaman çalıştırılacağı tam olarak bilinmemektedir.

Bundan dolayı dosya açık kalıp diğer programların erişimine kapanacak ve gereksiz bellek kullanacaktır.

Bu işlemi açıkca yapmak için IDisposable arayüzünü uygulayarak deneyelim.

using System;
using System.IO;

class Program {

    static void Main() {

        using(Sinif s1 = new Sinif("birdosya.txt")) { }
        Console.WriteLine("Uzun süren bir işlem.");
    }
}

class Sinif : IDisposable {

    private FileStream DosyaIslemleri = null;

    public Sinif(string dosyaYolu) {
        DosyaIslemleri = new FileStream(dosyaYolu, FileMode.OpenOrCreate);
    }

    public void Dispose() {
        Console.WriteLine("Kullanılan kaynaklar silindi.");
        DosyaIslemleri.Close();
        DosyaIslemleri = null;
    }

    ~Sinif() {}
}

Örnekte görüldüğü gibi kullanılan kaynakların serbest bırakıldığından emin olunmuştur.

C# Derslerine buradan ulaşabilirsiniz.

Hayırlı günler dilerim.

Yusuf SEZER

Yusuf SEZER

Computer Engineer who interested about web technologies, algorithms, artificial intelligence and embedded systems; constantly exploring new technologies.


Bunlara'da bakmalısın!