Я должен звонить, Располагают () на управляемых объектах?

Я не могу полагать, что все еще смущен этим, но, любой путь, позволяет, наконец закрепляют его:

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

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

Это корректно?


Спасибо за все ответы была, конечно, закреплена проблема.
Я рад, что был бдителен во всегда использовании 'использования' так, чтобы я не должен был проходить всю свою проверку кода. Я просто хотел быть ясным, что я не был бессмысленным пользователем.

Как в стороне, у меня действительно была странная ситуация, недавно, где я должен был заменить блок использования и вручную звонить, располагают! Я раскопаю это и создам новый вопрос.

28
задан Esoteric Screen Name 23 August 2012 в 16:50
поделиться

10 ответов

Это неверно . Вам необходимо удалить объекты, реализующие IDisposable . Вот почему они реализуют IDisposable - чтобы указать, что они оборачивают (прямо или косвенно) неуправляемые ресурсы.

В этом случае неуправляемый ресурс - это дескриптор GDI, и если вы не сможете их удалить, когда вы действительно закончили с ними, вы потеряете эти дескрипторы. Теперь у этих конкретных объектов есть финализаторы , которые будут вызывать освобождение ресурсов, когда срабатывает сборщик мусора, но у вас нет возможности узнать, когда это произойдет. Это может быть через 10 секунд, это может быть через 10 дней; Если ваше приложение не создает достаточной нагрузки на память, чтобы заставить GC включиться и запустить финализаторы на этих кистях / ручках / шрифтах / и т. д., вы можете закончить тем, что ОС не хватит ресурсов GDI до того, как GC когда-либо поймет, что происходит.

Кроме того, у вас нет гарантии, что каждая неуправляемая оболочка действительно реализует финализатор. Сама платформа .NET Framework довольно последовательна в том смысле, что классы, реализующие IDisposable , реализуют ее с правильным шаблоном , но вполне возможно, что некоторые другие классы могут имеют неработающую реализацию, которая не включает финализатор и, следовательно, не очищает должным образом, если для нее явно не вызывается Dispose .В общем, цель IDisposable состоит в том, что вы не должны знать или заботиться о конкретных деталях реализации; скорее, если он одноразовый, вы выбрасываете его, и точка.

Мораль истории: всегда выбрасывайте ID одноразовых предметов. Если ваш класс «владеет» объектами, которые являются IDisposable , то он должен реализовать сам IDisposable .

43
ответ дан 28 November 2019 в 02:48
поделиться

В вашем подходе есть явная ирония. Предварительно создав перья / кисти, вы точно создаете проблему, которую Dispose () пытается решить. Эти объекты GDI будут существовать дольше, как если бы вы не вызывали Dispose (). На самом деле еще хуже, они будут, по крайней мере, до закрытия формы.

Они, вероятно, существуют достаточно долго, чтобы перейти в поколение №2. Сборщик мусора не очень часто выполняет сборку второго поколения, теперь более важно вызывать для них Dispose (). Для этого переместите метод Dispose () формы из файла Designer.cs в файл form.cs и добавьте вызовы Dispose.

Но делайте это правильно. Ручки и кисти - очень дешевые предметы. Создавайте их, когда они вам нужны, в событии Paint. И используйте оператор using, чтобы избавиться от них сразу. Используйте класс Stopwatch, чтобы убедиться, что на самом деле это не вызывает замедления.

5
ответ дан 28 November 2019 в 02:48
поделиться

Вы профилировали это, чтобы увидеть, действительно ли создание и удаление этих объектов является проблемой? Я так не думаю.

Вы значительно упростите себе задачу и, определенно, снизите вероятность ошибок, просто следуя шаблону создания-в-использовании-блоке.

Если вы действительно хотите создать их один раз, также реализуйте IDisposable в своем классе-владельце и выполните итерацию Dispose для ваших собственных объектов. Нет необходимости в деструкторе (финализаторе).

Это почти не требует затрат на то, чтобы сделать это для объектов, которые на самом деле не нуждаются в Dispose, но если вы забудете Dispose для объекта, который действительно нуждается в нем, это будет дорого стоить.

2
ответ дан 28 November 2019 в 02:48
поделиться

Вам действительно нужно поискать документацию по кистям, ручкам и т. Д.

Если они не используют неуправляемые ресурсы, возможно, вам не придется вызывать Dispose. Но иногда шаблон using / Dispose используется "неправильно". В качестве примера рассмотрим платформу ASP.NET MVC. Здесь вы можете написать что-то вроде:

using(Html.BeginForm(...)){
  ///HTML input fields etc.
}

Когда вызывается Html.BeginForm (...) , будет выведен тег FORM . Когда оператор using завершается, Dispose будет вызываться для объекта, возвращенного из Html.BeginForm (...) . Вызов Dispose вызывает отображение конечного тега FORM . Таким образом, компилятор фактически принудительно объединит теги FORM, чтобы вы не забыли закрывающий тег.

1
ответ дан 28 November 2019 в 02:48
поделиться

Нет, Pen s и Brush es не являются не полностью управляемыми объектами.

Они содержат дескриптор неуправляемого ресурса, то есть соответствующего объекта GDI в базовой графической системе. (Не уверен в точной терминологии здесь ...)

Если вы не удалите их, дескрипторы не будут освобождены до тех пор, пока объекты не будут завершены сборщиком мусора, и нет никакой гарантии, что это произойдет в ближайшее время, или вообще.

1
ответ дан 28 November 2019 в 02:48
поделиться

Другие ссылались на «использование» блоков для объектов GDI - вот пример кода:

using( var bm = new Bitmap() )
using( var brush = new Brush() )
{

   // code that uses the GDI objects goes here
   ...

} // objects are automatically disposed here, even if there's an exception

Обратите внимание, что вы можете иметь столько строк «использования», сколько хотите для одного блока кода.

Я думаю, что это хороший и чистый способ работы с одноразовыми объектами.

1
ответ дан 28 November 2019 в 02:48
поделиться

Я написал компонент построения диаграмм GDI +, в котором использовалось множество перьев и кистей. Я создал их и разместил в блоке кода, который выполнял отрисовку, и производительность никогда не была проблемой. Лучше, чтобы потом иметь долгоживущий дескриптор, торчащий в ОС ИМХО.

3
ответ дан 28 November 2019 в 02:48
поделиться

Вам нужно их утилизировать.

Управляемый объект самостоятельно распоряжается своей памятью. Но память - не единственный ресурс, который использует объект. Dispose() предназначена для освобождения других ресурсов.

9
ответ дан 28 November 2019 в 02:48
поделиться

Нет, это неправильно. Я согласен с Aaronaught.

Кроме того, Microsoft рекомендует во время веб-трансляции в середине 2003 года, которую представил Дон Бокс, чтобы каждый разработчик .Net избавлялся от своих собственных объектов, как управляемых, так и неуправляемых, поскольку это повышает производительность кода до 20%. Если все сделать правильно, это может значительно улучшить производительность. Так что это основной навык, который должен знать и использовать каждый разработчик .net.

1
ответ дан 28 November 2019 в 02:48
поделиться

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

1
ответ дан 28 November 2019 в 02:48
поделиться
Другие вопросы по тегам:

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