IDisposable, делает это, действительно имеют значение

Прибытие из C/C++ давным-давно, у меня все еще есть привычка к обеспечению, что все ресурсы очищены правильно. Я всегда удостоверяюсь, Располагают, обращен, классы IDisposable и реализация Располагают шаблоны в моих классах, содержащих доступные объекты.

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

Они просто создают соединения с базой данных, открытые потоки и т.д., не звоня Близко или Располагают. Иногда они устанавливают локальную переменную, или членская переменная ни к "Чему" в конце метода (угадайте их образование).

Моя проблема состоит в том, что их код работает точно так же как мой. Код, который со временем создает тысячи объектов соединения с базой данных просто, работает.

Так, игнорируя какие-либо аргументы о правильности кода, после инструкций и т.д., IDiposable действительно имеет значение?

Кто-либо имеет, на самом деле исчерпал ресурсы от не Расположения объектов?

Править: Спасибо за все ответы. Интересный видеть, что у некоторых людей были проблемы, если не Располагающие. Это, кажется, редко, хотя и я предполагаю, что GC/JIT делает хорошее задание подавления использования ресурсов при нормальных условиях.

Ни мои коллеги, ни я не изменим поведение из-за этого, но оно чувствует себя хорошо для права.

11
задан adrianm 20 March 2010 в 20:00
поделиться

9 ответов

Да, я превысил максимальное количество курсоров Oracle при циклическом обращении к объекту соединения, например, потому что забыл закрыть считыватель команд - это было всего 100 циклов на одном соединении, а мне нужно было поддерживать это при возможном одновременном обращении сотен соединений.

Ваших коллег-разработчиков следует научить использовать using() { ... } синтаксис если они не могут потрудиться закрыть неуправляемые ресурсы самостоятельно. В любом случае, это хорошая практика, и вам тоже следует ее использовать, поскольку вы сами можете забыть поместить свои вызовы Dispose() в предложение finally {}, чтобы действительно произвести очистку в случае возникновения необработанного исключения.

Если вы не можете завоевать их сердца - измените их мысли - создайте тесты, которые ломают их код, максимально используя ресурсы, которые они не очищают - а затем покажите, что "исправление" просто и легко, и позволяет их коду быть гораздо более масштабируемым. Или просто покажите это своему боссу и скажите, что это позволит ему/ей продать продукт как новую версию с большей масштабируемостью :) Надеюсь, в будущем ваши коллеги-разработчики будут постоянно так делать, и вас тоже будут больше уважать.

26
ответ дан 3 December 2019 в 01:33
поделиться

Да, я также столкнулся с проблемой, когда объекты подключения к базе данных Oracle не удалялись.

Проблема Майка Атласа выше плохая, но, по крайней мере, было ясно, что пошло не так. Проблема, с которой мы столкнулись, заключалась в том, что время от времени при большой нагрузке сайт начинал выдавать ошибки, когда мы пытались открыть соединение, но к тому времени, когда мы посмотрели на систему, все это прояснилось (потому что сборщик гарабов очистил объекты и освободили пул соединений). Это было очень сложно воспроизвести, пока я не просмотрел код и не заметил, что соединение не закрывается в случае ошибки, изменение этого состояния на с использованием устранило всю проблему.

Короткий ответ заключается в том, что если объект прилагает усилия для реализации IDisposable, он существует по какой-то причине, поэтому ВСЕГДА удаляйте его, когда закончите, в идеале с помощью оператора using . Не умничайте и не хитрости с утилизацией иногда, но не в других случаях, когда вы не думаете, что вам нужно бла-бла-бла. Просто делайте то, что работает каждый раз.

Короче и удовлетворительнее ответ: вы правы, а ваши коллеги - идиоты, которые не знают, что делают.

3
ответ дан 3 December 2019 в 01:33
поделиться

Да, это важно. Когда объект реализует IDisposable, он явно заявляет, что он удерживает ресурсы, которые необходимо освободить, когда объект больше не нужен.

Большинство по-прежнему будут очищать свои ресурсы после завершения объекта, но завершение не является детерминированным и на него нельзя полагаться для управления ресурсами.

Простое размещение объявлений переменных в блоке using (...) упрощает правильное удаление.

5
ответ дан 3 December 2019 в 01:33
поделиться

Некоторые из этих ресурсов как ручки являются ограниченным ресурсом для всей системы, поэтому, если ваше приложение не выпускает эти другие приложения или даже ОС, могут пострадать. Взгляните на последнюю статью Марка Руссиновича о расширении границ серии Windows для примеров.

4
ответ дан 3 December 2019 в 01:33
поделиться

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

0
ответ дан 3 December 2019 в 01:33
поделиться

Неутилизация объектов IDisposable, освобождающих базу данных, - надежный и эффективный способ генерировать OutOfMemoryExceptions в средах.

DataSet реализует IDisposable, и я читал, что нет необходимости вызывать Dispose, потому что объекты, которые должны быть утилизированы для набора данных, создаются только во время проектирования (дизайнером visual studio). Я никогда не видел OOM от неутилизированных наборов данных (только OOM от огромных DataSets)

.
0
ответ дан 3 December 2019 в 01:33
поделиться

Помимо очевидных случаев (уже упомянутых) нехватки ресурсов, еще одним преимуществом IDisposable является то, что, поскольку он гарантирует, что Dispose () вызывается при выходе из блока , использующего , вы можете использовать его для всех разные вещи, даже вещи, которые не просто «выполняют операции с ресурсом ОС».

В этом смысле это похоже на замену для бедняков блокам Ruby или один небольшой вариант использования макросов Lisp.

0
ответ дан 3 December 2019 в 01:33
поделиться

Не удаляя (или не закрывая) соединения с базой данных, вы в конечном итоге укуситесь, да. Я видел, как это происходит.

1
ответ дан 3 December 2019 в 01:33
поделиться

Да, Да, Да , Это важно.

Недавно я профилировал приложение, которое никогда не профилировалось. Это просто приложение Winforms, ничего страшного, не так ли?

Неправильно.

Не реализуя IDisposible и не отменяя ссылки на обработчики событий, приложение теряло память как решето.

.NET Framework не освобождает вас от необходимости убирать за собой, она просто снижает вероятность того, что вы что-то сломаете, если вы этого не сделаете.

Потратьте час, профилируйте свое приложение с помощью ANTS Profiler . Это бесплатная пробная версия. Если вы не видите утечек памяти, продолжайте свой путь. Если да, то это потому, что вы полагались на .NET Framework как на свой костыль.

0
ответ дан 3 December 2019 в 01:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: