I'm using Microsoft's PrintHelper(Microsoft.Toolkit.Uwp.Helpers.PrintHelper) to print the pdf for my app. Now printing actually works by rendering the pdf into a BitmapImage
and thereby printing the BitmapImage
. This works fine for small number of pages. But when the number of pages increases, the memory consumption for rendering the BitmapImages goes high. Although I use garbage collection the memory is not released after the print operation. When the printing is performed a quite more number of times, the app gets crashed.
Is there any way to reduce this memory leak or to make the printing efficient?
Here is my code:
In this, the function GetImages()
returns the BitmapImages. PrintPreview
is the grid where the BitmapImages are displayed.
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();
}
}
Even though I force collect GC after the printing operation, the memory is not released.
private void PrintHelper_OnPrintSucceeded()
{
GC.Collect();
printHelper.ClearListOfPrintableFrameworkElements();
printHelper.Dispose();
GC.SuppressFinalize(this);
}
Edit:
Below is the GetImages() function.
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;
}
}