gpt4 book ai didi

wpf - 将 FixedDocument 保存到 XPS 文件会导致内存泄漏

转载 作者:行者123 更新时间:2023-12-04 03:09:16 25 4
gpt4 key购买 nike

我创建了一个 .NET Windows 服务,它执行某些操作并生成报告。这些报告是我保存在某个目录中的 XPS 文档。

熟悉 WPF,我选择的创建报告的方式是实例化一个 System.Windows.Documents.FixedDocument , 添加 FixedPage具有所需内容的对象。

我的问题是服务内存使用量随着时间的推移而不断增加。

起初,我严格地检查了我的代码,确保所有一次性对象都被处理,等等,以及其他明显的内存泄漏候选者,但仍然存在问题。然后我使用 CLR Profiler 来详细查看 Service 的内存使用情况。

我发现随着服务生成这些 FixedDocument报告,并将它们保存为 XPS 文件,所有与 FixedDocument 相关的各种 UI 元素|对象( DispatcherFixedPageUIElementCollectionVisual 等)留在内存中。

当我在 WPF 应用程序中做同样的事情时,这似乎不会发生,所以我的直觉是它与在 WPF 应用程序之外使用的 WPF UI Dispatcher 模型有关。

我如何“处置”我的 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的每一页上在得到它的分页器之前(如下面的答案所建议的)-我也试过通过 myFixedDocument直接进入Write()即不是分页器
  • 将这些代码行放在它们自己的线程中并手动关闭调度程序

  • 仍然没有运气。

    ========== 解决方法 ==========

    通过使用示例中所示的通用方法将上述代码隔离到自己的 AppDomain 中 http://msdn.microsoft.com/en-us/library/system.appdomain.aspx ,内存泄漏不再影响我的服务(我说“不再影响”,因为它仍然发生,但是当卸载 AppDomain 时,所有泄漏的资源都会随之卸载)。

    我仍然很想看到一个真正的解决方案。

    (在相关说明中,对于那些感兴趣的人,使用单独的 AppDomain 会导致我用来将某些 XPS 文件转换为 PDF 文件的 PDFSharp 组件中的内存泄漏。原来 PDFSharp 使用在正常情况下不会增长的全局字体缓存显着。但是在使用这些 AppDomains 后,缓存越来越大。我编辑了 PDFSharp 源代码,使我能够手动清除 FontDescriptorStock 和 FontDataStock,从而解决了问题。)

    ========== 解决方案 ==========

    有关最终解决方案,请参阅下面的答案。

    最佳答案

    我最终找到了一个答案,它分为两部分。

    首先,在将我的 XPS 文档保存到磁盘并关闭/处理 XpsDocument 之后,我运行以下代码行:

    Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.SystemIdle, new DispatcherOperationCallback(delegate { return null; }), null);

    这摆脱了所有 Dispatcher物体在内存中徘徊。

    虽然以上解决了大部分内存问题,但我注意到内存中仍然存在 FixedPage 对象和其他 UI 对象。手动清除我的 FixedDcoument 似乎摆脱了它们:
    foreach (var fixedPage in FixedDocument.Pages.Select(pageContent => pageContent.Child)) {
    fixedPage.Children.Clear();
    }

    关于wpf - 将 FixedDocument 保存到 XPS 文件会导致内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8742454/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com