Утилизация растрового изображения через его финализатор - PullRequest
1 голос
/ 12 мая 2010

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

Я посмотрел на отражатель для реализаций Image / Bitmap, и они, похоже, используют шаблон Dispose. Поэтому, даже если я не вызову Dispose (), CLR в конечном итоге вызовет его в другой раз.

Разве это плохо, если я просто оставлю растровые изображения такими, какие они есть, и пусть финализатор позаботится о них?

Ответы [ 4 ]

1 голос
/ 12 мая 2010

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

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

Но самый простой способ - просто позволить GC выполнить работу. Просто убедитесь, что все поля, на которые ссылаются обёртки, как можно скорее обнуляются.

1 голос
/ 12 мая 2010

Итак, даже если я не вызову Dispose (), CLR в конечном итоге вызовет его в другой раз.

Метод Finalizer и метод Dispose - это две разные вещи.Это «должно» сделать это, но вы не можете сказать наверняка, что так и будет.Вы не можете предполагать это, вам придется проверять в каждом конкретном случае.Из того, что вы говорите, в данном случае это звучит так, как будто это так.

Разве это плохо, если я просто позволю растровым изображениям оставаться такими, как они есть, и пусть финализатор позаботится о них?

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

Каждый раз, когда объект реализует IDisposable, он должен быть заключен в оператор using.

using(var bitmap = new BitMap())
{
....

}

В этом случаеТак как метод dispose находится в финализаторе, и вам действительно это нужно, вы не можете использовать метод dispose и позволить финализатору позаботиться об этом.Это не хорошо, но вы можете сделать это.Исходя из того, что вы говорите, это может быть лучшим вариантом действий без рефакторинга кода.

0 голосов
/ 13 мая 2010

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

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

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

Надеюсь, это поможет вам.

0 голосов
/ 12 мая 2010

Каково время жизни растровых изображений? Другими словами, что запускает создание растровых изображений и какие «события» происходят между ними и когда они могут быть безопасно уничтожены?

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

В C # было бы лучше обернуть их в using выражение:

using (Bitmap bitmap = CreateBitmap())
{
    DoWork(bitmap);
}

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

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

...