Освобождение кеша элемента управления изображением WPF

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

  Application.Current.Dispatcher.BeginInvoke(
            DispatcherPriority.Render,
            new Action(() =>
                           {
                               ms.Seek(0, SeekOrigin.Begin);
                               e.Image.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);


                               BitmapImage bitmapImage = new BitmapImage();
                               bitmapImage.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
                               bitmapImage.BeginInit();
                               bitmapImage.StreamSource = ms;
                               bitmapImage.CacheOption = BitmapCacheOption.None;
                               bitmapImage.EndInit();

                               CameraImageBox.BeginInit();
                               CameraImageBox.Source = bitmapImage;
                               CameraImageBox.EndInit();
                               bitmapImage = null;
                               ms.Flush();
                           }));

Элемент управления Image становится черным как смоль после пары десятков изображений, и весь пользовательский интерфейс перестает отвечать на запросы. Использование памяти достигает колоссального 1 гигабайта, я предполагаю, что кеш рендеринга элементов управления изображением не освобождается, поскольку e.Image является статическим ресурсом, который каждый раз перерисовывается.

Есть ли лучший способ сделать это, например, отобразить изображение в Rectangle или вручную освободить кеш?


person Sevki    schedule 17.09.2011    source источник
comment
Я думаю, вы должны распорядиться своим потоком памяти, поместив его, например, в блок использования, это неясно из вашего кода, где создается ms?   -  person Davide Piras    schedule 17.09.2011
comment
ms объявлен на уровне класса, это обработчик событий, который обрабатывает что-то каждый раз, когда обрабатывается новое изображение, этот код выполняется, поэтому я подумал, что было бы лучше сбросить ms и написать что-то там. Во всяком случае, ms, насколько моя отладка пошла, не кажется проблемой   -  person Sevki    schedule 17.09.2011


Ответы (1)


насколько я понимаю, вы добавляете изображение много раз в MemoryStream на каждой итерации.

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

// go to begin of stream
ms.Seek(0, SeekOrigin.Begin);

// write your bitmap content into the stream 
e.Image.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);

...
...
...
// flush to write content to the stream
ms.Flush();

теперь теоретически я понимаю, что вы все время перезаписываете одни и те же байты, но почему бы вам не разместить MemoryStream с блоком использования внутри вашего метода и не проверить результаты вместо того, чтобы открывать его как глобальную переменную?

person Davide Piras    schedule 17.09.2011