Q: I've built a process that iterates through all the pdf files in a
folder and sends them to the default printer. Each time it prints a
file, it takes some more memory and never releases it. Because each job
contains 100+ files, the memory used quickly exceeds that of the client
machine and ultimately crashes the application, etc...
I've isolated the line where the memory jump happens.
I've tried several different ways of destroying objects, but none
seem to get the memory back.
The code is a follows:
Imports System.IO
Imports System
Imports System.Drawing
Imports System.Drawing.Printing
Imports pdftron
Imports pdftron.PDF
Imports pdftron.Common
Imports pdftron.Filters
Public Class frmPrint
Private pdfdoc As PDFDoc = Nothing
Private pdfdraw As PDFDraw = Nothing
Private pageitr As PageIterator = Nothing
Private Sub btnBrowse_Click(ByVal sender As System.Object, ByVal e
As System.EventArgs) Handles btnBrowse.Click
FolderBrowserDialog1.ShowDialog()
txtFolder.Text = FolderBrowserDialog1.SelectedPath
End Sub
Private Sub btnPrint_Click(ByVal sender As System.Object, ByVal e
As System.EventArgs) Handles btnPrint.Click
Dim myFiles() As FileInfo
Dim oPDFTargetFolder As DirectoryInfo
Dim myTimer As Date
If Trim(txtFolder.Text) = "" Then
MessageBox.Show("Folder not specified.", "Invalid Folder",
MessageBoxButtons.OK, MessageBoxIcon.Warning)
Else
oPDFTargetFolder = New DirectoryInfo(txtFolder.Text)
If Not oPDFTargetFolder.Exists Then
MessageBox.Show("Folder does not exist.", "Invalid
Folder", MessageBoxButtons.OK, MessageBoxIcon.Warning)
Else
myFiles = oPDFTargetFolder.GetFiles("*.PDF")
If myFiles.GetLength(0) <= 0 Then
MessageBox.Show("No PDF files to print.", "No
Files", MessageBoxButtons.OK, MessageBoxIcon.Information)
Else
Me.Cursor = Cursors.WaitCursor
Array.Sort(myFiles, New CompareFileInfo)
For Each oFileInfo As FileInfo In myFiles
PDFPrint(txtFolder.Text, oFileInfo.Name)
'Just a timer to keep the printer queue under
control.
myTimer = Now
Do While
(Now.Subtract(myTimer).TotalSeconds < 6)
Loop
Next
'MessageBox.Show("Printing Complete.", "Printing
Complete", MessageBoxButtons.OK)
Me.Cursor = Cursors.Default
End If
End If
End If
End Sub
Private Sub PDFPrint(ByVal strFolder As String, ByVal strFile As
String)
Dim pdPrinter As PrintDocument = New PrintDocument
PDFNet.Initialize()
Try
Console.WriteLine("Opening the input file...")
pdfdoc = New PDFDoc(strFolder & "\" & strFile)
pdfdoc.InitSecurityHandler()
pageitr = pdfdoc.PageBegin
pdfdraw = New PDFDraw
pdfdraw.SetRasterizerType(PDFRasterizer.Type.e_BuiltIn)
AddHandler pdPrinter.PrintPage, AddressOf PrintPage
pdPrinter.Print()
pdfdoc.Close()
Catch e As PDFNetException
Console.WriteLine(e.Message)
End Try
PDFNet.Terminate()
End Sub
Private Sub PrintPage(ByVal sender As Object, ByVal ev As
PrintPageEventArgs)
Dim gr As Graphics = ev.Graphics
gr.PageUnit = GraphicsUnit.Inch
Dim rectPage As Rectangle = ev.PageBounds
Dim dpi As Single = gr.DpiX
If dpi > 300 Then dpi = 300
pdfdraw.SetDPI(dpi)
Dim left As Double = (rectPage.Left -
ev.PageSettings.HardMarginX) / 100
Dim right As Double = (rectPage.Right -
ev.PageSettings.HardMarginX) / 100
Dim top As Double = (rectPage.Top -
ev.PageSettings.HardMarginY) / 100
Dim bottom As Double = (rectPage.Bottom -
ev.PageSettings.HardMarginY) / 100
Dim rect As PDFTRON.PDF.Rect = New Rect(left * 72, bottom * 72,
right * 72, top * 72)
Try
'***********************************************************************
'This line causes the memory usage that never gets
released...!!
pdfdraw.DrawInRect(pageitr.Current, gr, rect)
'***********************************************************************
Catch ex As Exception
Console.WriteLine("Printing Error: " + ex.ToString)
End Try
pageitr.Next()
ev.HasMorePages = Not (pageitr = pdfdoc.PageEnd)
End Sub
End Class
---
A:
Since you are repeatedly re-creating PDFDraw objects you should call
pdfdraw.Close() just before pdfdoc.Close() in your PDFPrint method.
Otherwise pdfdraw objects may keep on accumulating because .NET garbage
collector is sometimes not very smart.
Another option is to allocate PDFDraw only one time and to keep on
reusing it to print/render all PDF documents.