XAML 到 XPS 内存泄漏
XAML to XPS memory leak
对于 windows 服务项目,我必须以 xps 格式制作报告。我有 xaml 代码,我将其转换为 xps 文档:
private void th_PrintErrorReport(OrderReportData reportData)
{
...
//Use the XAML reader to create a FlowDocument from the XAML string.
FlowDocument document = XamlReader.Load(new XmlTextReader(new StringReader(vRawXaml))) as FlowDocument;
//create xps file
using (XpsDocument xpsDoc = new XpsDocument(vFilePath, System.IO.FileAccess.Write, CompressionOption.Maximum))
{
// create a serialization manager
using (XpsSerializationManager rsm = new XpsSerializationManager(new XpsPackagingPolicy(xpsDoc), false))
{
// retrieve document paginator
DocumentPaginator paginator = ((IDocumentPaginatorSource)document).DocumentPaginator;
// save as XPS
rsm.SaveAsXaml(paginator);
rsm.Commit();
}
}
}
这可行,但不幸的是会造成内存泄漏,创建的每个报告都会在内存中留下 wpf 控件(contentpresent、标签等)。我用内存分析器检查了这个。我检查了像 this one and this one 这样的主题,这让我认为 wpf dispatcher/message 泵是问题所在。为了制作消息泵 运行,我将代码更改为:
public void StartHandling()
{
_ReportPrintingActive = true;
//xaml parsing has to run on a STA thread
_ReportPrintThread = new Thread(th_ErrorReportHandling);
_ReportPrintThread.SetApartmentState(ApartmentState.STA);
_ReportPrintThread.Name = "ErrorReportPrinter";
_ReportPrintThread.Start();
}
private void th_ErrorReportHandling()
{
Dispatcher.Run();
}
public void PrintErrorReport(OrderReportData reportData)
{
Action action = () =>
{
th_PrintErrorReport(reportData);
};
Dispatcher.FromThread(_ReportPrintThread).BeginInvoke(action);
}
但是还是没有成功。我错过了什么?
使用此 post 中的反射代码消除了内存泄漏:
对于 windows 服务项目,我必须以 xps 格式制作报告。我有 xaml 代码,我将其转换为 xps 文档:
private void th_PrintErrorReport(OrderReportData reportData)
{
...
//Use the XAML reader to create a FlowDocument from the XAML string.
FlowDocument document = XamlReader.Load(new XmlTextReader(new StringReader(vRawXaml))) as FlowDocument;
//create xps file
using (XpsDocument xpsDoc = new XpsDocument(vFilePath, System.IO.FileAccess.Write, CompressionOption.Maximum))
{
// create a serialization manager
using (XpsSerializationManager rsm = new XpsSerializationManager(new XpsPackagingPolicy(xpsDoc), false))
{
// retrieve document paginator
DocumentPaginator paginator = ((IDocumentPaginatorSource)document).DocumentPaginator;
// save as XPS
rsm.SaveAsXaml(paginator);
rsm.Commit();
}
}
}
这可行,但不幸的是会造成内存泄漏,创建的每个报告都会在内存中留下 wpf 控件(contentpresent、标签等)。我用内存分析器检查了这个。我检查了像 this one and this one 这样的主题,这让我认为 wpf dispatcher/message 泵是问题所在。为了制作消息泵 运行,我将代码更改为:
public void StartHandling()
{
_ReportPrintingActive = true;
//xaml parsing has to run on a STA thread
_ReportPrintThread = new Thread(th_ErrorReportHandling);
_ReportPrintThread.SetApartmentState(ApartmentState.STA);
_ReportPrintThread.Name = "ErrorReportPrinter";
_ReportPrintThread.Start();
}
private void th_ErrorReportHandling()
{
Dispatcher.Run();
}
public void PrintErrorReport(OrderReportData reportData)
{
Action action = () =>
{
th_PrintErrorReport(reportData);
};
Dispatcher.FromThread(_ReportPrintThread).BeginInvoke(action);
}
但是还是没有成功。我错过了什么?
使用此 post 中的反射代码消除了内存泄漏: