← Назад к вопросам
Для чего используется паттерн IDisposable?
2.0 Middle🔥 201 комментариев
#ASP.NET и Web API
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
IDisposable паттерн
IDisposable — это интерфейс для явного освобождения неуправляемых ресурсов (файлы, БД, сокеты).
Проблема
public class FileProcessor
{
private StreamReader _reader;
public FileProcessor(string path) => _reader = new StreamReader(path);
public string ReadLine() => _reader.ReadLine();
}
var proc = new FileProcessor("data.txt");
var line = proc.ReadLine();
// Файл остается открытым!
Решение с IDisposable
public class FileProcessor : IDisposable
{
private StreamReader _reader;
private bool _disposed = false;
public FileProcessor(string path) => _reader = new StreamReader(path);
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (_disposed) return;
if (disposing)
_reader?.Dispose();
_disposed = true;
}
~FileProcessor() => Dispose(false);
}
Использование
using (var proc = new FileProcessor("data.txt"))
{
var line = proc.ReadLine();
} // Dispose() вызовется автоматически
// Или C# 8+
using var proc = new FileProcessor("data.txt");
var line = proc.ReadLine();
// Dispose() при выходе из области видимости
Когда использовать
- Файлы и потоки (FileStream, StreamWriter)
- Подключения к БД (SqlConnection, DbContext)
- Сетевые соединения (TcpClient)
- Неуправляемые ресурсы (IntPtr)
- Таймеры (Timer)
Реальные примеры
// FileStream
using var stream = new FileStream("file.txt", FileMode.Open);
var content = await stream.ReadAsync(buffer, 0, buffer.Length);
// SqlConnection
using var conn = new SqlConnection(connectionString);
await conn.OpenAsync();
// DbContext
using var context = new AppDbContext();
var users = await context.Users.ToListAsync();
IAsyncDisposable
public class AsyncRepository : IAsyncDisposable
{
public async ValueTask DisposeAsync()
{
// асинхронная очистка ресурсов
}
}
await using var repo = new AsyncRepository();
Паттерн Dispose
- public Dispose() - явное освобождение
- protected virtual Dispose(bool) - для наследования
- ~Финализатор - страховка, если Dispose не вызван
- GC.SuppressFinalize() - убираем из очереди финализатора
Лучшие практики
- Всегда используй using statement для IDisposable
- Проверяй _disposed перед использованием
- Поддерживай наследование через protected virtual Dispose
- Для асинхронной очистки используй IAsyncDisposable
- Dokumentируй какие ресурсы освобождаются
IDisposable критичен для управления ресурсами и предотвращения утечек в .NET.