I am using the pdf stamper to encrypt the pdf with password. our requirement is to do 50 pdf files in parallel and size of each file can be upto 300 MB.
If I run the code and to encrypt the 50 files in parallel 2-3 times I get out of memory exception. Can you please help figureout what i am doing wrong ?
I even tried to use GC.Collect and GC.WaitForPendingFinalizers, but issue still exists.
I have created a test case below where i copy same file 50 times and execute them in parallel.
Thanks for your help.
My code is as follows :
private void button1_Click(object sender, EventArgs e)
{
try
{
int[] nums = Enumerable.Range(0, 50).ToArray();
string pdfTestDir = @"C:\ztemp\pdfTest";
string originalFile = @"C:\Ztemp\Original.pdf";
string newFile = @"C:\Ztemp\pdfTest\NewPdf_";
if (Directory.Exists(pdfTestDir)) { Directory.Delete(pdfTestDir, true); }
Directory.CreateDirectory(pdfTestDir);
if (Directory.Exists(pdfTestDir))
{
Parallel.ForEach<int>(nums, t =>
{
try
{
int userCopy = t + 1;
string newFilePath = newFile + userCopy.ToString() + ".pdf";
System.IO.File.Copy(originalFile, newFilePath);
ProtectPdf(newFilePath);
}
catch (Exception ex)
{
throw ex;
}
});
GC.Collect();
GC.WaitForPendingFinalizers();
}
MessageBox.Show("Done");
}
catch (Exception exc)
{
MessageBox.Show(exc.Message);
}
}
public void ProtectPdf(string file)
{
try
{
FileInfo fileInfo = new FileInfo(file);
string password = "password";
// Default strength; 128
var strength = PdfWriter.ENCRYPTION_AES_128;
// Get permission; default is PdfWriter.ALLOW_SCREENREADER
var permissions = PdfWriter.ALLOW_SCREENREADERS;
var tempInfo = new FileInfo(fileInfo.FullName.ToLower().Replace(".pdf", ".enrypted.pdf"));
if (tempInfo.Exists)
{
tempInfo.Delete();
}
var sInFilePath = fileInfo.FullName;
var sOutFilePath = tempInfo.FullName;
using (var existingFileStream = new FileStream(sInFilePath, FileMode.Open))
using (var newFileStream = new FileStream(sOutFilePath, FileMode.Create))
{
// Open existing PDF
var pdfReader = new PdfReader(existingFileStream);
// PdfStamper, which will create
var stamper = new PdfStamper(pdfReader, newFileStream);
try
{
stamper.SetEncryption(strength, password, password, permissions);
stamper.SetFullCompression();
stamper.Close();
stamper.Dispose();
pdfReader.Close();
pdfReader.Dispose();
newFileStream.Close();
newFileStream.Dispose();
existingFileStream.Close();
existingFileStream.Dispose();
}
catch (Exception ex)
{
stamper.Close();
stamper.Dispose();
pdfReader.Close();
pdfReader.Dispose();
throw ex;
}
}
fileInfo.Delete();
tempInfo.MoveTo(sInFilePath);
GC.Collect();
GC.WaitForPendingFinalizers();
}
catch (Exception ex)
{
throw ex;
}
}