
Вы неправильно используете IDisposable: почему using не спасает, когда объект утекает в другой поток
badcasedaily1 6 минут назад Вы неправильно используете IDisposable: почему using не спасает, когда объект утекает в другой поток Уровень сложности Средний Время на прочтение 5 мин Охват и читатели 190 Блог компании OTUS...
Anthropic — What company has the best second artificial intelligence model at the end of June?
В сфере искусственного интеллекта произошло заметное событие. badcasedaily1 6 минут назад Вы неправильно используете IDisposable: почему using не спасает, когда объект утекает в другой поток Уровень сложности Средний Время на прочтение 5 мин Охват и читатели 190 Блог компании OTUS C# * Программирование * . NET * Туториал Большинство C#-разработчиков знают правило: если объект реализует IDisposable , оберни его в using . В 80% случаев это работает.
Оставшиеся 20% начинаются, когда объект передаётся в другой метод, уходит в фоновый поток, живёт в DI-контейнере или попадает в коллекцию. В этих случаях using создаёт баги, которые неделями ловят в продакшене. using + return = закрытый объект Код, который выглядит правильно: using var connection = new SqlConnection(connectionString); await connection.
Технические детали
OpenAsync(); return connection; Метод открывает соединение и возвращает его. Using гарантирует Dispose при выходе из scope. Проблема в том, что выход из scope происходит сразу после return, и вызывающий код получает уже закрытое соединение.
На локальной машине с быстрой БД это может работать из-за connection pooling . В проде под нагрузкой вы получите ObjectDisposedException . Исправление: убрать using и переложить ответственность за Dispose на вызывающий код .
Это неприятно, потому что вызывающий должен знать, что ему вернули IDisposable , а если он передаст дальше, ответственность размывается. Но альтернатива хуже. Фоновый поток: using закрывает раньше, чем нужно public void StartProcessing() { using var stream = File.
Отраслевые последствия
Run(() => ProcessStream(stream)); } Using закрывает stream при выходе из StartProcessing . Run запускает обработку в фоне. Получается гонка: если ProcessStream начнёт читать после закрытия stream , будет ObjectDisposedException .
Если успеет до, всё работает. Нестабильный баг, который воспроизводится только под нагрузкой. Правильный вариант: передать владение потоку.
public void StartProcessing() { var stream = File. Run(async () => { try { await ProcessStream(stream); } finally { await stream. DisposeAsync(); } }); } Тот, кто реально использует ресурс, тот и освобождает.
Этот прогресс даёт важные сигналы о будущем отрасли, и технологический мир внимательно наблюдает.





