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;
}
}