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

Diğer Kategoriler

C#’da IDisposable ve Using Deyimleri Nasıl Birlikte Çalışır

Tim Corey
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 temizlenmesi olmadan, 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 uygun kaynak yönetimini nasıl sağladığına ve nasıl kullanıldığını temizleme işlemelerini basitleştirdiğine dair net, uygulamalı bir açıklama sunar. Bu makalede, gösterisinin her adımını inceleyecek ve bu desenin yönetilmeyen kaynakları verimli bir şekilde serbest bırakmaya ve kaynak kaçaklarını önlemeye nasıl yardımcı olduğunu anlayacağız.

IDisposable ve Kaynak Yönetimine Giriş

Tim, IDisposable'ı "uygulamanız için uygun kaynak yönetimini ve güvenliğini sağlamak için güçlü bir araç" olarak tanımlayarak başlıyor. Yönetilmeyen kaynakların - veritabanı bağlantıları, dosya akışları veya sistem tanıtıcıları gibi - çö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 toplama süreci tarafından otomatik olarak ele alınır. Sorun, bir sınıfın işletim sistemi düzeyindeki bellek veya dosya tanıtıcıları gibi yönetilmeyen kod veya kaynaklarla doğrudan etkileşime girdiğinde ortaya çıkar - çünkü bunlar .NET çalışma zamanının kontrolü dışında kalır.

Tim, yönetilmeyen kaynakların açıkça serbest bırakılmazsa, tahsis edilmiş durumda kalacağını ve bellek sızıntılarına ve zayıf sistem performansına yol açacağını vurgular. IDisposable arayüzü, geliştiricilere nesnenin ömrü sona erdiğinde kaynakları temizlemek için belirleyici bir mekanizma sağlamak amacıyla tasarlanmıştır.

Kaynak Kullanımını Simüle Etme

Temizlik ihtiyaçını göstermek için Tim, DemoResource sınıfı içeren küçük bir konsol uygulaması oluşturur. Sınıf, bir veritabanı bağlantısını açmayı ve kapamayı 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 kaynakları içeren tipik bir iş akışını temsil eder - örneğin bir veritabanına bağlantı kurmak veya bir dosyaya yazmak gibi. DoWork() içindeki işlemler, yönetilmeyen kaynakları doğrudan kullandığımızda ne olacağını simüle eder.

İşler Yanlış Gittiğinde — Kaynak Kaçakları

Yaklaşık 2 dakika civarında, Tim, işlemin düzgün tamamlanmadığında ne olduğunu gösterir. İş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 meydana geldiğinde, program "Bağlantı Kapatılıyor" satırına asla ulaşamaz — bu, yönetilmeyen kaynağın açık kaldığı anlamına gelir.

Tim, bağlı veritabanı bağlantılarını kapatamayan uygulamalar yüzünden sunucuların her gece yeniden başlatılması gerektiği erken deneyimlerini hatırlar. Bu kapatılmamış bağlantılar birikerek, tüm mevcut belleği ve soketleri tüketirdi. Bu, eksik veya hatalı temizlik mantığı nedeniyle kaynak kaçaklarının klasik bir örneğidir.

IDisposable'ın Rolü

Bunu düzeltmek için Tim, Dispose yöntemini tanımlayan IDisposable arayüzüyle tanıştırır. IDisposable uygulamak, bu sınıfın serbest bırakılacak kaynaklara sahip olduğunu ve bunların nasıl serbest bırakılacağını tanımlar.

Tim sınıfına : IDisposable ekler ve yöntemi 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 yöntemi, yönetilmeyen belleği serbest bırakmak, dosya tanıtıcılarını kapatmak veya veritabanı bağlantılarını serbest bırakmak gibi kaynak temizleme işlemleri için ayrılmış bir yer görevi görür.

Tim, bu Dispose metodunun, istisnalar meydana geldiğinde bile temizlik işleminin güvenilir bir şekilde yürütülmesini sağlayan bir using ifadesi kullanılarak otomatik olarak çağrılabileceğini açıklar.

Using Cümleleri ve Kesin Temizlik

Tim, using'in C#'da iki farklı anlam ifade edebileceğini netleştirir:

  • Using yönergesi — dosyanın üst kısmında (örn., using System;)

  • Kaynak temizliği için using ifadesi

İkincisini gösterir:

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

Bu ifadenin kapsamının sonunda, derleyici otomatik olarak Dispose yöntemini çağırır. Bu, kesin temizlik sağlar — yani kaynak, kullandıktan hemen sonra serbest bırakılır, nesnenin daha sonra çöpte toplanmasını beklemek yerine.

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

Bir İstisna Meydana Geldiğinde Ne Olur

Tim, istisnayı yeniden tanıtır ve gösterimi yeniden çalıştırır. İstisna normal akışı kesintiye uğratsa bile, çıktı 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 temizliği garanti ettiğini gösterir. Bu, sonlandırma mantığının bir finally bloğu içine yerleştirilmesine eşdeğerdir; ancak çok daha temiz ve okunabilirdir.

Bu, C# IDisposable deseninin gücüdür — kodunuzun her parçasında manuel temizlik gerektirmeden, yönetilen veya yönetilmeyen kaynakların doğru şekilde serbest bırakılmasını garanti eder.

Using'in Kapsamı ve Dispose'un Ne Zaman Çağrıldığı

Tim, ardından kapsamın düzeltilme zamanlamasını nasıl etkilediğini keşfeder. Using bildirim bittiğinde, derleyici otomatik olarak Dispose() çağrısı ekler.

Başka bir satır koyduğunuzda gösterir:

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

using ifadesinin sonrasına, bu satırın Dispose() çağrılmadan önce çalıştırılacağını, çünkü çözümlemenin geçerli kapsamın sona erdiğinde gerçekleştiğini (örneğin metodun sonu) açıklar.

Çözümlemeyi daha önce meydana getirmek için, Tim kodu bir using bloğu içine 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 yönteminin, objenin bloğun sonunda kapsam dışında kaldığı gibi son yazdırma ifadesinden önce yürütülür.

Bu, kaynak kodun yürütmesinin bitişiyle birlikte kaynakların mutlak temizlenmesini sağlayarak kaynakların hemen serbest bırakıldığını gösterir.

Tam Dispose Deseni (Genişletilmiş Konsept)

Tim'in gösterimi temel unsurlara 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 temizlenmesine, türetmeye destek verir ve çift temizlemeyi önler. Desen genellikle şu şekilde 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;
        }
    }
}

İşte neler oluyor:

  • Dispose(bool disposing), yönetilen nesnelerin kullanımdan kaldırılıp kaldırılmadığını (dispose true olduğunda) ve yönetilmeyen kaynakların serbest bırakılmasını ayırt eder (her zaman gereklidir).

  • disposing parametresi, çöp toplama sırasında yönetilen nesnelerin serbest bırakılmasını engellemeye yardımcı olur; çünkü çöp toplayıcı onları zaten geri almış olabilir.

  • GC.SuppressFinalize(this), manuel temizleme yapıldıktan sonra çöp toplayıcının sondölüm metodunu çağırmasını engeller.

  • protected virtual void Dispose(bool disposing), türetilmiş sınıfların dispose davranışını protected override void Dispose(bool disposing) kullanarak özelleştirmesine olanak tanır.

Bu, etkili kaynak yönetimini sağ ayağa kaldırır, kaynak kaçaklarını önler ve hem yönetilen hem de yönetilmeyen kaynaklar için güvenli bir temizlik mantığı sağlar.

Neden Uygun Temizlik Önemlidir

Tim'in örneği Dispose desenini doğru bir şekilde uygulamanın önemini vurgular - veri tabanı bağlantılarını kapatmanın yanı sıra yönetilmeyen belleği, dosya tanıtıcılarını ve sistem kaynaklarını zarifçe ele almayı da içerir. IDisposable'ı uygulayarak ve nesneleri using ifadeleri içinde sarmalayarak, şunları sağlarsınız:

  • Kaynaklar derhal serbest bırakılır.

  • Çöp toplama, yönetilmeyen kaynaklarla ilgilenmek zorunda kalmaz.

  • Bellek kullanımı optimal kalır

  • Uygulamalar kararlı ve verimli kalır

Sonuç

Tim'in videosunda özetlediği gibi, IDisposable arayüzü ve using ifadesi el ele çalışarak istisnalar meydana geldiğinde bile temizliğin otomatik olarak gerçekleşmesini garanti eder.

Dispose desenini uygulayarak, nesnelerinizin yönetilen ve yönetilmeyen kaynaklarını nasıl özgür bırakacağınıza dair tam kontrol elde edersiniz ve using bloğu bu sürecin ne olursa olsun doğru anda tetiklenmesini sağlar.

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

"IDisposable'ı using ifadesiyle kullandığınızda, Dispose yöntemi kapsamın sonunda mutlaka çağrılacaktır - istisna olsa da olmasa da." — Tim Corey

Özetle, C# IDisposable desenini anlamak ve uygulamak, kaynak temizliği konusunda ustalaşmak, sızıntıları önlemek ve uygulama istikrarını artırmak için önemli bir adımdır.

Hero Worlddot related to C#’da IDisposable ve Using Deyimleri Nasıl Birlikte Çalışır
Hero Affiliate related to C#’da IDisposable ve Using Deyimleri Nasıl Birlikte Çalışır

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

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

Iron Destek Ekibi

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