Немножко о PictureBox и памяти.

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

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

Итак задача: делаем приложение в котором есть PictureBox и ImageList, приложение «мониторит» определённые параметры и в зависимости от того чего «намониторило» меняет изображение в PictureBox на одно из коллекции ImageList.

Казалось бы, чего проще…
pictureBox1.Image = imageList1.Images[номер_картинки];

Но не тут то было, оказывается если сделать так определённое количество раз (довольно большое количество, но думаю зависит от размера изображений), то спустя некоторое время получим Ошибку по памяти. Судя по всему при таком способе память от предыдущего изображения остаётся занятой, при этом добавляется блок памяти под новое. Вообщем помогает это исправить Dispose().

Чтобы всё было хорошо, сколько бы изображение не менялось, делать надо так:
pictureBox1.Image.Dispose();
pictureBox1.Image = imageList1.Images[номер_картинки];

При таком варианте ошибок не возникает.

Вот-так. Век живи — век учись.

7 комментариев

avatar
> приложение «мониторит» определённые параметры и в зависимости от того чего «намониторило» меняет изображение в PictureBox на одно из коллекции ImageList.

А можете привести пример кода?
avatar
Вот например — делал маленькую графическую менюшку, для мобильного устройства из четырёх пунктов.
Процедурка прорисовывает выбранный элемент активным и предыдущий выбранный неактивным.

— В ImageList1 — изображения неактивных менюшек.
— В ImageList2 — изображения активных менюшек.

— num_prev_menu — индекс предыдущего выбранного пункта (для отмены выделения).
— num_menu — индекс текущего выбранного пункта меню (для выделения).

private void repaint_menu()
        {
            switch (num_prev_menu)
            {
                case 1:
                    pictureBox1.Image.Dispose();
                    pictureBox1.Image = imageList1.Images[0];
                    break;
                case 2:
                    pictureBox2.Image.Dispose();
                    pictureBox2.Image = imageList1.Images[1];
                    break;
                case 3:
                    pictureBox3.Image.Dispose();
                    pictureBox3.Image = imageList1.Images[2];
                    break;
                case 4:
                    pictureBox4.Image.Dispose();
                    pictureBox4.Image = imageList1.Images[3];
                    break;
            }

            switch (num_menu)
            {
                case 1:
                    pictureBox1.Image.Dispose();
                    pictureBox1.Image = imageList2.Images[0];
                    break;
                case 2:
                    pictureBox2.Image.Dispose();
                    pictureBox2.Image = imageList2.Images[1];
                    break;
                case 3:
                    pictureBox3.Image.Dispose();
                    pictureBox3.Image = imageList2.Images[2];
                    break;
                case 4:
                    pictureBox4.Image.Dispose();
                    pictureBox4.Image = imageList2.Images[3];
                    break;
            }

        }


— Если убрать Dispose — и зажать кнопку перебора менюшек — спустя непродолжительное время получим memory error.
avatar
Спасибо! У меня приложение работает на десктопе, отображает курсы валют и изменение курса по сравнению со вчерашним днем. Я думаю, что если не включу метод Dispose(), то это будет не так критично.
avatar
кстати, при включении
pictureBox3.Image.Dispose();

получаю NullReferenceException
avatar
Возможно дело просто в том что pictureBox — пустой, перед Dispose — надо в него что нибудь (изображение) положить.
avatar
Да, уже разобрался. Спасибо!
avatar
естественно нельзя уничтожить то, чего ещё нет.
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.