Dispose in .NET

Recently we were working on merging PDFs on our web site where we ran into a strange problem. The user could run the merged reports once but upon the second time the server would get a “File Locked” error. Here’s the original code:

public static string CreateMergedPdf(string targetPdf, List<string> pdfFiles)
{
    using (FileStream stream = new FileStream(targetPdf, FileMode.Create))
    {
       Document pdfDoc = new Document(PageSize.LETTER);
       PdfCopy pdf = new PdfCopy(pdfDoc, stream);
       pdfDoc.Open();

       foreach (string file in pdfFiles)
       {
          pdf.AddDocument(new PdfReader(file));
       }

       if (pdfDoc != null)
       {
          pdfDoc.Close();
       }
    }

    return targetPdf;
}

Seems simple enough but we obviously aren’t cleaning up our work as the files are still locked.  After searching for all places where we were referencing disposable objects. We finally came up with this:

public string CreateMergedPdf(string targetPdf, List<string> pdfFiles)
{
   using (var stream = new FileStream(targetPdf, FileMode.Create))
   {
      using (var pdfDoc = new Document(PageSize.LETTER))
      {
         using (var pdf = new PdfCopy(pdfDoc, stream))
         {
            pdf.Open();
            pdfDoc.Open();
            foreach (var file in pdfFiles)
            {
               var reader = new PdfReader(file);
               pdf.AddDocument(reader);
               reader.Dispose();
            }
            pdf.Close();
         }
         pdfDoc.Close();
       }
       stream.Close();
   }

   return targetPdf;
}

 

The lessons learned were clear by the end, you must close and dispose when you are able. Another thing to note was the

pdf.AddDocument(new PdfReader(file));

was from an example, causing us to waste time looking for the last remnant of the locking situation.