TGViewer
.NET Разработчик .NET Разработчик @netdeveloperdiary · 6.77K subscribers
Post #971 1.38K
День семьсот восемьдесят девятый. #ЗаметкиНаПолях
Мои любимые ошибки с IDisposable. 1/3
System.IDisposable - фундаментальный интерфейс, используемый в большинстве программ .NET. Его основная цель - предоставить механизм для высвобождения «неуправляемых» ресурсов: файловых потоков, подключений к базам данных, сетевых сокетов и т.д.
public interface IDisposable {
void Dispose();
}
Что может быть проще? Кроме того, для него есть специальный синтаксис - оператор using:
using(var stream=File.OpenText("…")) {
// неуправляемый ресурс stream
// живёт внутри этого блока
}
// здесь stream удаляется
Красиво и просто!

Но несмотря на эту простоту, удивительно легко выстрелить себе в ногу, неверно используя IDisposable. Вот мои любимые ошибки.

1. IDisposable вам врёт
Кажется, интерфейс легко реализовать: всего один метод void, и готово! Но IDisposable обманывает. К нему предъявляются некоторые требования, которые нельзя выразить посредством простого объявления интерфейса:
- взаимодействие со сборщиком мусора через финализаторы,
- взаимодействие с подклассами,
- обработка повторных вызовов Dispose.
Для решения всех этих проблем мы используем паттерн Dispose. Это настолько распространенная проблема, что IDE и статические анализаторы могут подсказывать вам, как правильно реализовать IDisposable.

В этом отношении IDisposable нарушает некоторые из наших фундаментальных предположений о полноте интерфейсов C#: недостаточно, чтобы компилятор был доволен, мы должны читать документацию, следить за подсказками статических анализаторов и удовлетворять любые их требования, которые компилятор не сможет проверить.

К сожалению, это обычное дело. Например:
- В IEquatable<T>, вы также должны переопределить базовые реализации Equals(Object) и GetHashCode().
- В IComparable<T>, вы должны перегрузить op_GreaterThan, op_GreaterThanOrEqual и т.п.
- Класс, реализующий IFormattable, должен поддерживать формат «G» (общий)…

Библиотеки базовых классов изобилуют подобными хитростями! Обязательно используйте какие-нибудь анализаторы, чтобы они помогали вам с этим.

2. Разработчики IDisposable могут вам врать
Мы уже знаем, что нам нужно использовать шаблон Dispose для наших реализаций IDisposable. А что насчёт использования чужих реализаций? Например, правильно ли SqlConnection использует шаблон Dispose? У нас нет другого способа узнать это, кроме как читать документацию.

Самый большой нарушитель, с которым я столкнулся, - это HttpClient. Обычно мы хотим освободить наши неуправляемые ресурсы как можно скорее. Реализуя IDisposable, HttpClient посылает нам сигнал о том, что он хочет находиться в блоке using:
using(var client = new HttpClient()) {
// выполняем запрос
}
Но использование HttpClient таким образом всё испортит. В документации мы находим следующий перл:
HttpClient предназначен для однократного создания и повторного использования в течение всего жизненного цикла приложения. Создание экземпляра класса HttpClient для каждого запроса при больших нагрузках исчерпает количество доступных сокетов.

Это ошибка замечательна тем, что всё отлично работает при разработке и ручном тестировании, но падает даже при небольшой нагрузке. Использование IHttpClientFactory - хорошее решение этой проблемы.

Продолжение следует…

Источник:
https://www.lazy-electron.com/2021/03/06/favorite-idisposable-bugs.html
Автор оригинала - Ryan Davis
More from @netdeveloperdiary
  1. Oct 11, 2026День 2811. #ВопросыНаСобеседовании Марк Прайс предложил свой набор из 60 вопросов (как тех…
  2. Oct 10, 2026День 2810. #ЧтоНовенького #VSCode Более Быстрый и Лёгкий C# Dev Kit Мы, разработчики, люби…
  3. Oct 9, 2026День 2809. #Карьера 5 Навыков, Которые Помогут Быстрее Стать Сеньором. Окончание Начало 3.…
  4. Oct 8, 2026День 2808. #Карьера 5 Навыков, Которые Помогут Быстрее Стать Сеньором. Начало В ИТ есть се…
  5. Oct 7, 2026День 2807. #ЗаметкиНаПолях Типы Коллекций в .NET, Которые Стоит Попробовать. Окончание Нач…
  6. Oct 6, 2026🦈 Открытое собеседование на Middle C# | 6 октября, 19:00 МСК Приглашаем на открытое собес…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →