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 alınmasına izin vermek için veya IAsyncDisposable arabirimini uygularIDisposable. uygulayan IDisposablebir nesne kullanmayı bitirdiğinizde, açıkça temizleme gerçekleştirmek için nesnesinin Dispose veya DisposeAsync uygulamasını çağırırsınız. Bunu iki şekilde yapabilirsiniz:

  • C# using deyimi veya bildirimiyle (Using Visual Basic'te).
  • Bir try/finally blok uygulayarak ve içinde veya DisposeAsync yöntemini finallyçağırarakDispose.

Önemli

VEYA bilgisi olmadığından GC nesnelerinizi atmıyor.IDisposable.Dispose()IAsyncDisposable.DisposeAsync() 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? ve DisposeAsyncuygulama Dispose hakkında ek ayrıntılar için bkz:

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

Using deyimi

C# deyimi veUsingVisual Basic'teki deyimi, bir nesneyi temizlemek için yazmanız gereken kodu basitleştirir.using deyimi using bir veya daha fazla kaynak alır, belirttiğiniz deyimleri yürütür ve nesneyi otomatik olarak atar. 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 System.IO.StreamReader nesnesi oluşturmak ve serbest bırakmak için deyimini using 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, ayraçların kaldırıldığı ve kapsam belirlemenin ö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.
            //
        }
    }
}

sınıfı yönetilmeyen bir kaynak kullandığını belirten arabirimini uygulasa StreamReaderIDisposable da, örnek açıkça yöntemini çağırmaz StreamReader.Dispose . C# veya Visual Basic derleyicisi deyimiyle karşılaştığında using , açıkça bir try/finally blok içeren aşağıdaki koda eşdeğer olan 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 bloğu deyimine using sarmalamak try/finally yerine bloğu doğrudan uygulamayı try/finally seçebilirsiniz. Bu, kişisel kodlama stiliniz olabilir veya aşağıdaki nedenlerden biri için bunu yapmak isteyebilirsiniz:

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

Aşağıdaki örnek, bir nesnenin örneğini oluşturmak, kullanmak ve atmak ve oluşturucu ReadToEnd ve yöntemi tarafından StreamReader atılan özel durumları işlemek için bir StreamReader blok kullanması try/catch/finally dışında önceki örneğe benzer. Bloktaki finally kod, uygulayan IDisposable nesnenin yöntemini çağırmadan Dispose önce olmadığını null denetler. Bunun yapılmaması, çalışma zamanında bir NullReferenceException özel duruma 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 using deyimi desteklemediğinden ancak yönteme doğrudan çağrılara izin vermediğinden, bir try/finally blok uygulamayı seçerseniz veya uygulamanız gerekiyorsa bu temel deseni Dispose izleyebilirsiniz.

IDisposable örnek üyeleri

Bir sınıf bir örnek alanı veya özelliğine sahipse ve türü uyguluyorsa IDisposable, sınıfı da uygulaması IDisposablegerekir. Daha fazla bilgi için bkz . Art arda atma uygulama.

Ayrıca bkz.