Altbilgi içeriğine atla
Iron Academy Logo
C# Uygulaması
C# Uygulaması

Diğer Kategoriler

C#'da IDisposable ve Kullanım Deyimleri Nasıl Birlikte Çalışır

[[academy-video-youtube({"vid": "C4qzrFeYHgs", "start_time": "0", "title": "İDisposable ve Using Deyimleri C#'ta Nasıl Birlikte Çalışır", "creator": "Tim Corey", "length": "10m 00s"})]]

Kaynak yönetimi, herhangi bir C# geliştiricisinin en kritik sorumluluklarından biridir. Dosya tanıtıcıları, veritabanı bağlantıları veya yönetilmeyen bellek gibi kaynakların düzgün bir şekilde temizlenmemesi durumunda, uygulamalar hızla performans sorunları, bellek sızıntıları veya hatta sistem çökmeleriyle karşılaşabilir.

Tim Corey, "How IDisposable and Using Statements Work Together in C#" adlı videosunda, C# IDisposable deseninin doğru kaynak yönetimini nasıl sağladığını ve using deyiminin temizlemeyi nasıl basitleştirdiğini açıklayan net ve uygulamalı bir sunum gerçekleştiriyor. Bu makalede, yönetilmeyen kaynakların verimli bir şekilde serbest bırakılmasını ve kaynak sızıntılarının önlenmesini nasıl sağladığını anlamak için gösterisini adım adım takip edeceğiz.

IDisposable ve Kaynak Yönetimine Giriş

Tim, IDisposable'ı "uygulamanızın doğru kaynak yönetimi ve güvenliği için güçlü bir araç" olarak tanımlayarak başlar. Veritabanı bağlantıları, dosya akışları veya sistem tanıtıcıları gibi yönetilmeyen kaynakların, çöp toplayıcı tarafından otomatik olarak temizlenmediğini açıklar.

Buna karşılık, yönetilen kaynaklar (dizeler veya normal C# nesneleri gibi) çöp toplayıcı işlemi tarafından otomatik olarak ele alınır. Bir sınıfın işletim sistemi seviyesi bellek veya dosya tanıtıcıları gibi yönetilmeyen kod veya yönetilmeyen kaynaklarla doğrudan etkileşimde bulunduğunda sorun ortaya çıkar—çünkü bunlar .NET çalışma zamanının kontrolü dışında kalır.

Tim, eğer yönetilmeyen kaynaklar açıkça bırakılmazsa, tahsis edildikleri durumda kalacaklarını, bu da bellek sızıntılarına ve kötü sistem performansına neden olacağını vurgular. IDisposable arayüzü, geliştiricilere belirli bir temizlik mekanizması - bir nesnenin yaşam süresi sona erdiğinde kaynakları temizlemenin garanti edilen bir yolu - sağlamak üzere tasarlanmıştır.

Kaynak Kullanımını Simüle Etme

Temizleme gereksinimini göstermek için Tim, bir DemoResource sınıfı içeren küçük bir konsol uygulaması oluşturur. Sınıf, bir veritabanı bağlantısını açıp kapatmayı simüle eden bir DoWork() yöntemi içerir:

public class DemoResource
{
    public void DoWork()
    {
        Console.WriteLine("Opening Connection");
        Console.WriteLine("Doing Work");
        Console.WriteLine("Closing Connection");
    }
}
public class DemoResource
{
    public void DoWork()
    {
        Console.WriteLine("Opening Connection");
        Console.WriteLine("Doing Work");
        Console.WriteLine("Closing Connection");
    }
}

Bu, yönetilmeyen kaynaklarla ilgili tipik bir iş akışını temsil eder - örneğin, bir veritabanına bağlanmak ya da bir dosyaya yazmak. DoWork() içindeki işlemler, yönetilmeyen kaynakları doğrudan kullandığımızda neler olabileceğini simüle eder.

Yanlış Giden Durumlar — Kaynak Sızıntıları

Yaklaşık 2 dakikalık sürede, Tim sürecin doğru bir şekilde tamamlanmadığında neler olduğunu gösteriyor. İşlem sırasında bir hatayı simüle etmek için bir istisna ekler:

throw new Exception("I broke");
throw new Exception("I broke");

Bu istisna gerçekleştiğinde, program "Bağlantı Kapatılıyor" satırına asla ulaşmaz - yani yönetilmeyen kaynak açık kalır.

Tim, veritabanı bağlantılarını kapatmayı başaramayan uygulamalar nedeniyle sunucuların her gece yeniden başlatılması gereken erken deneyimlerini anımsar. Bu kapanmayan bağlantılar, kullanılabilir tüm bellek ve soketleri tüketerek birikir. Bu, eksik veya yanlış temizleme mantığı nedeniyle klasik bir kaynak sızıntısı örneğidir.

IDisposable'ın Rolü

Bunu düzeltmek için Tim, Dispose metodunu tanımlayan IDisposable arayüzünü tanıtır. IDisposable'ı uygulamak, .NET'e bu sınıfın serbest bırakılacak kaynakları olduğunu söyler ve bunların nasıl serbest bırakılması gerektiğini tanımlar.

Tim, sınıfına : IDisposable ekler ve metodu uygular:

public class DemoResource : IDisposable
{
    public void Dispose()
    {
        Console.WriteLine("Closing Connection via Dispose");
    }
}
public class DemoResource : IDisposable
{
    public void Dispose()
    {
        Console.WriteLine("Closing Connection via Dispose");
    }
}

Dispose metodu, yönetilmeyen bellek serbest bırakma, dosya tanıtıcılarını kapatma veya veritabanı bağlantılarını serbest bırakma gibi kaynak temizleme için ayrılmış bir yer olarak hizmet eder.

Tim, bu Dispose metodunun using deyimini kullanarak otomatik olarak çağrılabileceğini açıklar, bu sayede temizleme işlemi düzgün bir şekilde gerçekleştirilir — istisnalar gerçekleştiğinde bile.

Using Deyimleri ve Belirleyici Temizlik

Tim, using'in C#'ta iki farklı anlam ifade edebileceğini açıklar:

  • Dosyanın başında kullanılan using yönergesi (örneğin, using System;)

  • Kaynak temizleme için using deyimi

Sonuncusunu gösterir:

using DemoResource demo = new DemoResource();
demo.DoWork();
using DemoResource demo = new DemoResource();
demo.DoWork();

Bu deyimin kapsamının sonunda, derleyici otomatik olarak Dispose metodunu çağırır. Bu, belirleyici temizlemeyi sağlar — yani kaynak, kullanıldıktan hemen sonra serbest bırakılır, daha sonra çöp toplayıcının nesneyi sonlandırmasını beklemek yerine.

Bu yaklaşım, tüm atılabilir nesnelerin doğru zamanda uygun bir şekilde temizlenmesini sağlayarak, uygulama kararlılığını ve bellek kullanım verimliliğini artırır.

İstisna Oluştuğunda Ne Olur

Tim, istisnayı yeniden tanıtır ve demoyu yeniden çalıştırır. İstisna normal akışı kesintiye uğratmasına rağmen, çıktıda Dispose()'ın hala çağrıldığını gösterir:

Opening Connection
Doing Work
I broke
Closing Connection via Dispose
Opening Connection
Doing Work
I broke
Closing Connection via Dispose

Bu, using bloğunun hatalar sırasında bile temizleme sağladığını gösterir. Bu, temizleme mantığını bir finally bloğu içine yerleştirmeye eşdeğerdir, ancak çok daha temiz ve okunabilir.

Bu, C# IDisposable deseni'nin gücüdür — bu, kodunuzun her bölümünde manuel temizlik gerektirmeden, tüm yönetilen veya yönetilmeyen kaynakların düzgün bir şekilde serbest bırakılmasını sağlar.

Using İçeriğinin Kapsamı ve Dispose Ne Zaman Çağrılır

Tim, kapsamın bertaraf etme zamanlamasını nasıl etkilediğini araştırır. Kullanım deklarasyonu sona erdiğinde, derleyici otomatik olarak Dispose() çağrısını ekler.

Kullanım deyiminden sonra başka bir satır eklediğini gösterir:

Console.WriteLine("I'm done running Program.cs");
Console.WriteLine("I'm done running Program.cs");

Bu satır, mevcut kapsamın (örneğin yöntemin sonu gibi) sona ermesi ile bertaraf gerçekleştiği için Dispose() çağrılmadan önce çalıştırılır.

Bertarafın daha erken gerçekleşmesi için, Tim kodu bir using bloğuna sarar:

using (DemoResource demo = new DemoResource())
{
    demo.DoWork();
}
Console.WriteLine("I'm done running Program.cs");
using (DemoResource demo = new DemoResource())
{
    demo.DoWork();
}
Console.WriteLine("I'm done running Program.cs");

Şimdi, Dispose metodu, nesne bloğun sonunda kapsamının dışına çıktığı için, nihai yazdırma ifadesinden önce çalışır.

Bu, kod bloğunun gerçekleştirdiği işlemler sona erdiğinde kaynakların hemen serbest bırakılmasını sağlayan belirleyici kaynak temizliği örneğini gösterir.

Tam Bertaraf Deseni (Genişletilmiş Kavram)

Tim'in demo temel bilgilere odaklansa da, üretim kodunda kullanılan tam C# Dispose desenine doğal olarak yol açar. Bu desen, hem yönetilen hem de yönetilmeyen kaynakların güvenli bir şekilde temizlenmesini, kalıtımı destekler ve çift temizlemeyi önler. Desen genellikle şöyle görünür:

public class BaseResource : IDisposable
{
    private bool disposed = false; // To detect redundant calls

    // Public dispose method
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    // Protected virtual dispose method
    protected virtual void Dispose(bool disposing)
    {
        if (!disposed)
        {
            if (disposing)
            {
                // Dispose managed resources here
            }

            // Free unmanaged resources here
            disposed = true;
        }
    }
}
public class BaseResource : IDisposable
{
    private bool disposed = false; // To detect redundant calls

    // Public dispose method
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    // Protected virtual dispose method
    protected virtual void Dispose(bool disposing)
    {
        if (!disposed)
        {
            if (disposing)
            {
                // Dispose managed resources here
            }

            // Free unmanaged resources here
            disposed = true;
        }
    }
}

Burada neler oluyor:

  • Dispose(bool disposing), yönetilen nesnelerin bertarafı (disposing doğru olduğunda) ile yönetilmeyen kaynakların serbest bırakılması (her zaman gereklidir) arasında ayrım yapar.

disposing parametresi, çöp toplama sırasında yönetilen nesnelerin serbest bırakılmasını engellemeye yardımcı olur

  • GC.SuppressFinalize(this), manuel bertaraf tamalandığında çöp toplayıcının sonlandırıcıyı çağırmasını önler.

  • protected virtual void Dispose(bool disposing), türetilmiş sınıfların protected override void Dispose(bool disposing) kullanarak bertaraf davranışını geçersiz kılmalarına olanak tanır.

Bu, etkin kaynak yönetimi sağlar, kaynak sızıntılarını önler ve hem yönetilen hem de yönetilmeyen kaynaklar için güvenli temizleme mantığı sağlar.

Neden Doğru Temizlik Önemlidir

Tim'in örneği, yalnızca veritabanı bağlantılarını kapatmakla kalmayıp, aynı zamanda yönetilmeyen belleği, dosya tanıtıcılarını ve sistem kaynaklarını zarif bir şekilde ele alacak şekilde Dispose desenini doğru bir şekilde uygulamanın önemini vurgular. IDisposable uygulayarak ve using deyimleri içinde nesneleri sarmalayarak, şunları sağlarsınız:

  • Kaynaklar zamanında serbest bırakılır

  • Çöp toplama yönetilmeyen kaynaklarla uğraşmak zorunda kalmaz

  • Bellek kullanımı optimum kalır

  • Uygulamalar sağlam ve verimli kalır

Sonuç

Tim'in videosunda özetlediği gibi, IDisposable arayüzü ve using deyimi, istisnalar meydana gelse bile temizliğin otomatik olarak gerçekleşmesini sağlamak için birlikte çalışır.

Dispose desenini uygulayarak, nesnelerinizin yönetilen ve yönetilmeyen kaynaklarını nasıl serbest bıraktığını kontrol edersiniz, while the using bloğu, bu sürecin doğru anda tetiklenmesini sağlar — ne olursa olsun.

Bu kombinasyon, C#'ta etkili kaynak yönetiminin bel kemiğini oluşturur, kararlı, verimli ve sızıntısız uygulamalar sağlar.

"Bir using deyimiyle IDisposable kullandığınızda, Dispose methodu her zaman kapsamın sonunda - istisna olsun ya da olmasın - çağrılır." — Tim Corey

Kısacası, C# IDisposable desenini anlamak ve uygulamak, kaynak temizliği, sızıntıları önleme ve uygulama kararlılığına ulaşma yolunda önemli bir adımdır.

Hero Worlddot related to C#'da IDisposable ve Kullanım Deyimleri Nasıl Birlikte Çalışır
Hero Affiliate related to C#'da IDisposable ve Kullanım Deyimleri Nasıl Birlikte Çalışır

Sevdiğiniz Şeyleri Paylaşarak Daha Fazla Kazanın

.NET, C#, Java, Python veya Node.js ile çalışan geliştiriciler için içerik oluşturuyor musunuz? Uzmanlığınızı ek gelire dönüştürün!

Iron Destek Ekibi

Haftada 5 gün, 24 saat çevrimiçiyiz.
Sohbet
E-posta
Beni Ara