Aracılığıyla paylaş


IDisposable uygulayan nesneleri kullanma

Ortak dil çalışma zamanının çöp toplayıcısı (GC), yönetilen nesneler tarafından kullanılan belleği geri alır. Genellikle, yönetilmeyen kaynakları kullanan türler, yönetilmeyen kaynakların geri kazanılmasına izin vermek için IDisposable veya IAsyncDisposable arabirimini uygular. IDisposable'yi uygulayan bir nesneyi kullanmayı bitirdiğinizde, açıkça temizlik yapmak için nesnenin Dispose veya DisposeAsync uygulamasını çağırırsınız. Bunu iki yoldan biriyle yapabilirsiniz:

  • C# using ifadesi veya bildirimiyle (Using Visual Basic'te).
  • Bir try/finally bloğu uygulayarak ve Dispose veya DisposeAsync yöntemini finally içinde çağırarak.

Önemli

GC'nin ve bilgisi olmadığından, nesnelerinizi IDisposable.Dispose(). GC yalnızca bir nesnenin sonlandırılabilir olup olmadığını (yani bir Object.Finalize() yöntemi tanımlayıp tanımlamadığını) ve nesnenin sonlandırıcısının ne zaman çağrılması gerektiğini bilir. Daha fazla bilgi için bkz. Sonlandırma nasıl çalışır? Ek ayrıntılar için Dispose ve DisposeAsync uygulamasına bakın:

System.IDisposable veya System.IAsyncDisposable arabirimlerini uygulayan nesneler, aksi açıkça belirtilmediği sürece, değişken kapsamına bakılmaksızın her zaman düzgün bir şekilde imha edilmelidir. Yönetilmeyen kaynakları serbest bırakmak için bir sonlandırıcı tanımlayan türler genellikle GC.SuppressFinalize veya Dispose uygulamalarından DisposeAsync çağrır. SuppressFinalize çağrısı, GC'ye sonlandırıcının zaten çalıştırıldığını ve nesnenin sonlandırma için teşvik edilmemesi gerektiğini belirtir.

using deyimi

using C# deyimi veUsing Visual Basic'teki deyimi, bir nesneyi temizlemek için yazmanız gereken kodu basitleştirir. using deyimi bir veya daha fazla kaynağı edinir, belirttiğiniz deyimleri yürütür ve nesneyi otomatik olarak yok eder. Ancak, using deyimi yalnızca oluşturulduğu yöntem kapsamında kullanılan nesneler için yararlıdır.

Aşağıdaki örnek, bir using nesnesi oluşturmak ve serbest bırakmak için System.IO.StreamReader deyimini kullanır.

using System.IO;

class UsingStatement
{
    static void Main()
    {
        var buffer = new char[50];
        using (StreamReader streamReader = new("file1.txt"))
        {
            int charsRead = 0;
            while (streamReader.Peek() != -1)
            {
                charsRead = streamReader.Read(buffer, 0, buffer.Length);
                //
                // Process characters read.
                //
            }
        }
    }
}
Imports System.IO

Module UsingStatement
    Public Sub Main()
        Dim buffer(49) As Char
        Using streamReader As New StreamReader("File1.txt")
            Dim charsRead As Integer
            Do While streamReader.Peek() <> -1
                charsRead = streamReader.Read(buffer, 0, buffer.Length)
                ' 
                ' Process characters read.
                '
            Loop
        End Using
    End Sub
End Module

Bildirimusing, parantezlerin çıkarıldığı ve kapsamın örtük olduğu alternatif bir söz dizimidir.

using System.IO;

class UsingDeclaration
{
    static void Main()
    {
        var buffer = new char[50];
        using StreamReader streamReader = new("file1.txt");

        int charsRead = 0;
        while (streamReader.Peek() != -1)
        {
            charsRead = streamReader.Read(buffer, 0, buffer.Length);
            //
            // Process characters read.
            //
        }
    }
}

StreamReader sınıfı IDisposable arabirimini, yönetilmeyen bir kaynak kullandığını belirten, uygulasa da, StreamReader.Dispose yöntemini açıkça çağırmaz olan örnek. C# veya Visual Basic derleyicisi using ifadesine rastladığında, bu, açıkça bir try/finally bloğu içeren aşağıdaki koda eşdeğer olan bir ara dil (IL) yayar.

using System.IO;

class TryFinallyGenerated
{
    static void Main()
    {
        var buffer = new char[50];
        StreamReader? streamReader = null;
        try
        {
            streamReader = new StreamReader("file1.txt");
            int charsRead = 0;
            while (streamReader.Peek() != -1)
            {
                charsRead = streamReader.Read(buffer, 0, buffer.Length);
                //
                // Process characters read.
                //
            }
        }
        finally
        {
            // If non-null, call the object's Dispose method.
            streamReader?.Dispose();
        }
    }
}
Imports System.IO

Module TryFinallyGenerated
    Public Sub Main()
        Dim buffer(49) As Char
        Dim streamReader As New StreamReader("File1.txt")
        Try
            Dim charsRead As Integer
            Do While streamReader.Peek() <> -1
                charsRead = streamReader.Read(buffer, 0, buffer.Length)
                ' 
                ' Process characters read.
                '
            Loop
        Finally
            If streamReader IsNot Nothing Then DirectCast(streamReader, IDisposable).Dispose()
        End Try
    End Sub
End Module

C# using deyimi, iç içe using yerleştirilmiş deyimlerle dahili olarak eşdeğer olan tek bir deyimde birden çok kaynak edinmenizi de sağlar. Aşağıdaki örnek, iki StreamReader farklı dosyanın içeriğini okumak için iki nesne örneği oluşturur.

using System.IO;

class SingleStatementMultiple
{
    static void Main()
    {
        var buffer1 = new char[50];
        var buffer2 = new char[50];

        using StreamReader version1 = new("file1.txt"),
                           version2 = new("file2.txt");

        int charsRead1, charsRead2 = 0;
        while (version1.Peek() != -1 && version2.Peek() != -1)
        {
            charsRead1 = version1.Read(buffer1, 0, buffer1.Length);
            charsRead2 = version2.Read(buffer2, 0, buffer2.Length);
            //
            // Process characters read.
            //
        }
    }
}

Try/finally bloğu

Bir try/finally bloğunu using deyimine sarmak yerine, try/finally bloğunu direkt olarak uygulamayı seçebilirsiniz. Bu, kişisel kodlama stiliniz olabilir veya aşağıdaki nedenlerden biri için bunu yapmak isteyebilirsiniz:

  • Blokta catch oluşan özel durumları işlemek için bir try blok eklemek için. Aksi takdirde, using deyimi içerisinde meydana gelen tüm özel durumlar işlenmez.
  • Kapsamı içinde bildirildiği bloğun yerel olmayan bir nesnesini uygulayan IDisposable bir nesnenin örneğini oluşturma.

Aşağıdaki örnek, bir try/catch/finally blok kullanarak bir StreamReader nesnesinin örneğini oluşturmak, kullanmak ve atmak ile StreamReader oluşturucu ve ReadToEnd yöntemi tarafından atılan özel durumları işlemek için önceki örneğe benzer. finally bloğundaki kod, IDisposable uygulayan nesnenin null olmadığını doğruladıktan sonra Dispose yöntemini çağırır. Bunun yapılmaması çalışma zamanında bir NullReferenceException istisnaya neden olabilir.

using System;
using System.Globalization;
using System.IO;

class TryExplicitCatchFinally
{
    static void Main()
    {
        StreamReader? streamReader = null;
        try
        {
            streamReader = new StreamReader("file1.txt");
            string contents = streamReader.ReadToEnd();
            var info = new StringInfo(contents);
            Console.WriteLine($"The file has {info.LengthInTextElements} text elements.");
        }
        catch (FileNotFoundException)
        {
            Console.WriteLine("The file cannot be found.");
        }
        catch (IOException)
        {
            Console.WriteLine("An I/O error has occurred.");
        }
        catch (OutOfMemoryException)
        {
            Console.WriteLine("There is insufficient memory to read the file.");
        }
        finally
        {
            streamReader?.Dispose();
        }
    }
}
Imports System.Globalization
Imports System.IO

Module TryExplicitCatchFinally
    Sub Main()
        Dim streamReader As StreamReader = Nothing
        Try
            streamReader = New StreamReader("file1.txt")
            Dim contents As String = streamReader.ReadToEnd()
            Dim info As StringInfo = New StringInfo(contents)
            Console.WriteLine($"The file has {info.LengthInTextElements} text elements.")
        Catch e As FileNotFoundException
            Console.WriteLine("The file cannot be found.")
        Catch e As IOException
            Console.WriteLine("An I/O error has occurred.")
        Catch e As OutOfMemoryException
            Console.WriteLine("There is insufficient memory to read the file.")
        Finally
            If streamReader IsNot Nothing Then streamReader.Dispose()
        End Try
    End Sub
End Module

Programlama diliniz bir try/finally deyimi desteklemediğinden ancak using yöntemine doğrudan çağrılara izin verdiğinden, bir Dispose blok uygulamayı seçerseniz veya uygulamanız gerekiyorsa bu temel deseni izleyebilirsiniz.

IDisposable örnek üyeleri

Bir sınıf, bir örnek alanına veya özelliğe sahipse ve türü IDisposable'i uyguluyorsa, sınıfın da IDisposable'i uygulaması gerekir. Daha fazla bilgi için bkz. Bir kademeli imha uygulama.

Ayrıca bakınız