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önteminifinally
ç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 DisposeAsync
uygulama 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 veUsing
Visual 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 bircatch
blok eklemek için. Aksi takdirde, deyimi içindeusing
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.