我正在使用Microsoft的PrintHelper(Microsoft.Toolkit.Uwp.Helpers.PrintHelper)为我的应用程序打印pdf。现在,通过将pdf渲染到BitmapImage
中并由此打印BitmapImage
来实际进行打印。这对于少数页面来说效果很好。但是,当页面数量增加时,用于渲染BitmapImages的内存消耗将变高。尽管我使用垃圾回收,但是打印操作后内存不会释放。当执行多次打印时,该应用程序将崩溃。
有什么方法可以减少内存泄漏或提高打印效率?
这是我的代码:
在此函数GetImages()
返回BitmapImages。 PrintPreview
是显示BitmapImages的网格。
public async Task PrintAsync()
{
GC.Collect();
foreach (var image in await GetImages())
{
Grid grid = new Grid();
var printpreview = new PrintPreview(image);
grid.Children.Add(printpreview);
printHelper.AddFrameworkElementToPrint(grid); printpreview = null;
grid = null;
GC.Collect();
}
}
即使我在打印操作后强行收集GC,也不会释放内存。
private void PrintHelper_OnPrintSucceeded()
{
GC.Collect();
printHelper.ClearListOfPrintableFrameworkElements();
printHelper.Dispose();
GC.SuppressFinalize(this);
}
编辑:
下面是GetImages()函数。
public async Task<IEnumerable<ImageSource>> GetImages(int qualityRatio = 2)
{
GC.Collect();
if (pdf_stream != null)
{
StorageFolder myfolder = ApplicationData.Current.LocalFolder;
StorageFile pdf_file;
pdf_file = await myfolder.CreateFileAsync(filename + ".pdf", CreationCollisionOption.GenerateUniqueName);
using (Stream outputStream = await pdf_file.OpenStreamForWriteAsync())
{
await pdf_stream.AsStreamForRead().CopyToAsync(outputStream);
}
var result = new List<ImageSource>();
try
{
var document = await PdfDocument.LoadFromFileAsync(pdf_file);
for (uint i = 0; i < document.PageCount; i++)
{
using (var page = document.GetPage(i))
{
using (var memoryStream = new MemoryStream())
{
using (var randomStream = memoryStream.AsRandomAccessStream())
{
var image = new BitmapImage();
var options = new PdfPageRenderOptions
{
DestinationWidth = (uint)page.Size.Width * (uint)qualityRatio,
DestinationHeight = (uint)page.Size.Height * (uint)qualityRatio
};
await page.RenderToStreamAsync(randomStream, options);
image.SetSource(randomStream);
result.Add(image);
}
}
}
}
}
catch { }
return result;
}
return null;
}
PrintPreview.xaml
<Page
x:Class="App.src.PrintPreview"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid>
<Image Source="{Binding}" Stretch="Uniform" Margin="0"></Image>
</Grid>
PrintPreview.xaml.cs
public sealed partial class PrintPreview : Page
{
public PrintPreview(ImageSource image)
{
this.InitializeComponent();
this.DataContext = image;
}
}
答案 0 :(得分:1)
通过测试,您可以额外创建一个Image控件,首先将BitmapImage传递给Image.Source,然后使用randomStream设置Source,它将节省一些内存。
MainPage.xaml:
<Image x:Name="Output" Visibility="Collapsed" ></Image>
MainPage.cs:
using (var page = document.GetPage(i))
{
var stream = new InMemoryRandomAccessStream();
await page.RenderToStreamAsync(stream);
BitmapImage src = new BitmapImage();
Output.Source = src; // pass bitmapImage to Source
await src.SetSourceAsync(stream);
stream.Dispose();
result.Add(src);
}
此外,我发现与使用流加载bitmapImage相比,使用 urisource 可以节省更多的内存。但是您需要将每个页面从pdf转换为StorageFile并将其保存在temp文件夹中,然后使用UriSource将其转换为bitmapImage。这比较复杂,但是您也可以尝试进行检查。
答案 1 :(得分:0)
我没有评论员,但是:请尝试调用属性Dispose()
的{{1}}方法。