Мне интересно, есть ли утечка .net EventHandler
вокруг CroppedBitmap и RenderTargetBitmap.Это вызывает у меня огромный кошмар!
Мое приложение WPF выполняет постоянно выполняющийся вызов рендеринга со скоростью 60 кадров в секунду.Я заметил, что через некоторое время воспроизводимый контент становился все медленнее и медленнее.
После долгих исследований, включая профилирование в visual studio и использование профилировщика памяти ANTS, я сузил его до использования CroppedBitmap.
У меня есть некоторый простой код demonstration of problem
, который включает в себя ...
RenderTargetBitmap srcBitmap = new RenderTargetBitmap((int)scaledWidth, (int)scaledHeight, 96, 96, PixelFormats.Default);
RenderTargetBitmap destBitmap = new RenderTargetBitmap((int)scaledWidth, (int)scaledHeight, 96, 96, PixelFormats.Default);
<code loop>
{...
DrawingVisual DV = new DrawingVisual();
DrawingContext DC = DV.RenderOpen();
var srcRec = new Int32Rect(x,y,w,h);
var srcCrop = new CroppedBitmap(srcBitmap, srcRec);
var destRec = new Rect(.....);
DC.DrawImage(srcCrop, destRec);
DC.Close();
destBitmap.Render(DV);
DC = null;
DV = null;
...}
После вызова CroppedBitmap с использованием srcBitmap к srcBitmap добавляется обработчик событий.В частности, если вы разберетесь с этим до более высокого уровня, установка CroppedBitmap.Source = srcBitmap добавит этот обработчик событий.
CroppedBitmap имеет события DownloadCompleted, DownloadFailed, DownloadProgress.Я бы предположил, что это DownloadCompleted.
Проверка количества EventHandlers (с использованием свойства _downloadEvent в srcBitmap / RenderTargetBitmap), это действительно увеличивается на единицу при каждом вызове CroppedBitmap - и никогда не уменьшается.Я могу только прийти к выводу, что CroppedBitmap добавляет обработчик событий в RenderTargetBitmap, который никогда не удаляется.Через некоторое время это заканчивается обработчиками событий x000 на RenderTargetBitmap, которые, как я полагаю, проходит через .net и вызывают мое снижение скорости.
Я не могу на всю жизнь понять, чтоделать с этим!Изображение устанавливается на простой элемент управления изображением, ничего особенного.
Я пытался отследить, когда это происходит в недрах платформы .net, построчно, шаг за шагом, но теряюсь, когдаотладчик начинает попадать в оптимизированные библиотеки .net, не может копать дальше.
Представление растрового изображения простое ...
Content.Source = srcBitmap;
....
<Image x:Name="Content" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" RenderOptions.BitmapScalingMode="LowQuality" Stretch="None" IsHitTestVisible="False"></Image>
Просто чтобы прояснить, например,код может выполняться без рендеринга, рисования и т. д., только новый код CroppedBitmap ... необходим для демонстрации такого поведения.Другие строки были включены выше для полноты.Ничего не меняет.
Приведенный выше пример был запущен на .NET Framework 4.7.2, чтобы убедиться, что в последней версии возникла эта проблема.
Я также попытался заморозить CroppedBitmap, на всякий случайразница.Очевидно нет.Фактически, вызов srcCrop.Freeze привел к тому, что srcBitmap.isFrozen был истинным!хм ..... так что кажется, что CroppedBitmap вносит изменения в растровое изображение, против которого он обрезается?
Не удалось найти никакой информации, справки, статей и т. д. по вышеуказанному: (
Обратите внимание, что это не утечка памяти в RenderTargetBitmap, о которой вы упоминали на форумах поддержки, это что-то другое. Запустите этот код без CroppedBitmap, и это нормально. Я использую RenderTargetBitmaps в нескольких местах, все хорошо (и я также уже учитываю увеличение использования памяти какописано в этой статье, и я уже вызываю GC.Collect и т. д.) Я также повторно использую мои RenderTargetBitmaps, поэтому они создаются только один раз (возможно, поэтому обработчики событий накапливаются, когда к ним применяется несколько CroppedBitmap).
Я пытался использовать отражатель, чтобы поймать создаваемые обработчики событий, чтобы я мог удалить их вручную, но (несмотря на различные примеры в Интернете) не может достать, где бы они ни скрывались, чтобы сделать это.где-нибудь!
Кто-нибудь есть идеи, что я мог бы сделать, чтобыисправить это?
Спасибо за вашу помощь заранее ...