Сохранение FixedDocument в файл XPS приводит к утечке памяти

Я создал .NET Windows Service, который выполняет определенные действия и генерирует отчеты. Эти отчеты являются документами XPS, которые я сохраняю в определенном каталоге.

Будучи знакомым с WPF, я решил создать отчеты для создания экземпляраSystem.Windows.Documents.FixedDocument, добавивFixedPage объекты с содержанием по мере необходимости.

Моя проблема заключается в том, что использование служебной памяти с течением времени увеличивается и увеличивается.

Сначала я тщательно просмотрел свой код, убедившись, что все одноразовые объекты были уничтожены и т. Д., И других очевидных кандидатов на утечку памяти, но все еще имел проблему. Затем я использовал CLR Profiler, чтобы подробно рассмотреть использование сервиса Сервисом.

Я обнаружил, что, поскольку сервис генерирует этиFixedDocument отчеты и сохраняет их в виде файлов XPS, все различные элементы пользовательского интерфейса, связанные сFixedDocument объекты (Dispatcher, FixedPage, UIElementCollection, Visualи т. д.) остаются в памяти.

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

Как я могу "распоряжаться" своимFixedDocument объекты при использовании их в таком сервисе (или вообще вне приложения WPF)?

======== РЕДАКТИРОВАТЬ =========

Хорошо, я обнаружил, что утечка памяти не связана с созданием / заполнением FixedDocument. Если я это сделаю, но на самом деле никогда не сохраню его на диск в формате XPS, утечки памяти не произойдет. Итак, моя проблема должна быть связана с сохранением в виде файла XPS.

Вот мой код:

var paginator = myFixedDocument.DocumentPaginator;
var xpsDocument = new XpsDocument(filePath, FileAccess.Write);
var documentWriter = XpsDocument.CreateXpsDocumentWriter(xpsDocument);                         
documentWriter.Write(paginator);
xpsDocument.Close();

Что я пробовал:

Ручная сборка мусорапризваниеUpdateLayout() на каждой страницеmyFixedDocument до того, как получить его paginator (как предложено в ответе ниже) - я также пытался пройтиmyFixedDocument прямо вWrite() то есть не пагинаторПоместить эти строки кода в их собственный поток и вручную отключить диспетчеры

Все еще не повезло.

========== Временное решение ==========

Выделив приведенный выше код в свой собственный домен приложения, используя общий метод, показанный в примере наhttp://msdn.microsoft.com/en-us/library/system.appdomain.aspxутечка памяти больше не влияет на мой сервис (я говорю «больше не влияет», потому что это все еще происходит, но когда AppDomain выгружен, все утечки ресурсов выгружаются с ним).

Я все еще хотел бы увидеть реальное решение.

(Для связанного примечания, для заинтересованных, использование отдельного AppDomain вызвало утечку памяти в компоненте PDFSharp, который я использовал, чтобы превратить определенные файлы XPS в файлы PDF. Оказывается, PDFSharp использует глобальный кэш шрифтов, который в нормальных условиях не растет значительно. Но кэш рос и рос после использования этих доменов приложений. Я отредактировал исходный код PDFSharp, чтобы я мог вручную очистить FontDescriptorStock и FontDataStock, решая проблему.)

========== РЕШЕНИЕ ==========

Смотрите мой ответ ниже для окончательного решения.

Ответы на вопрос(2)

Ваш ответ на вопрос