title: C# technique for deleting a file from web server immediately after closing
body: <p>I'm creating PDF invoices in a C# MVC application that I'm attaching to an email and sending, ideally, once the email is sent I'd like to delete the invoice to free up server space and improve privacy/security. I've written code to do it but it fails 50% of the time because the file is locked by another process (I'm not sure if it's the create/write process that's locking it or the email send). I'm sending the email asynchronously (i.e. the code to delete doesn't execute until the email has sent).</p>
  
  <p>I'd appreciate some tips on how to handle this problem. I could run a job to clean up old files but I'd prefer to clean them up as I go...</p>
  
  <p>I forgot to mention I am using iTextSharp to generate the PDF - the crux of it is this code is used to generate the final invoice (I am able to delete the list of files passed in as a param without drama):</p>
  
  <pre><code>/// &lt;summary&gt;
          /// http://stackoverflow.com/questions/4276019/itextsharp-pdfcopy-use-examples
          /// &lt;/summary&gt;
          /// &lt;param name="fileNames"&gt;&lt;/param&gt;
          /// &lt;param name="outFile"&gt;&lt;/param&gt;
          private void CombineMultiplePDFs(List&lt;string&gt; files, string outFile)
          {
              int pageOffset = 0;
              int f = 0;
  
              iTextSharp.text.Document document = null;
              PdfCopy writer = null;
  
              foreach (string file in files)
              {
                  // we create a reader for a certain document
                  PdfReader reader = new PdfReader(file);
                  reader.ConsolidateNamedDestinations();
                  // we retrieve the total number of pages
                  int n = reader.NumberOfPages;
  
                  pageOffset += n;
  
                  if (f == 0)
                  {
                      // step 1: creation of a document-object
                      document = new iTextSharp.text.Document(reader.GetPageSizeWithRotation(1));
                      // step 2: we create a writer that listens to the document
                      writer = new PdfCopy(document, new FileStream(outFile, FileMode.Create));
                      // step 3: we open the document
                      document.Open();
                  }
                  // step 4: we add content
                  for (int i = 0; i &lt; n; )
                  {
                      ++i;
                      if (writer != null)
                      {
                          PdfImportedPage page = writer.GetImportedPage(reader, i);
                          writer.AddPage(page);
                      }
                  }
                  PRAcroForm form = reader.AcroForm;
  
                  if (form != null &amp;&amp; writer != null)
                  {
                      writer.CopyAcroForm(reader);
                  }
  
                  f++;
              }
  
              // step 5: we close the document
              if (document != null)
              {
                  document.Close();
              }
          }
  </code></pre>
  
  <p>The PDF File is then sitting on the server (e.g. "~/Invoices/0223.pdf") ready to attach to an email like so:</p>
  
  <pre><code>MailMessage mailMessage = new MailMessage();
          mailMessage.From = new MailAddress(WebConfig.GetWebConfigKey(AppSettingsKey.ReplyEmailAddress.ToString()));
          mailMessage.To.Add(new MailAddress(user.Email));
          mailMessage.Subject = emailTemplate.TemplateSubject;
          mailMessage.Body = emailTemplate.TemplateContent;
          mailMessage.IsBodyHtml = false;
          mailMessage.Attachments.Add(new Attachment(HttpContext.Current.Server.MapPath("/Invoices/" + invoiceId + ".pdf")));
  
          SmtpClient client = new SmtpClient();
  
          try
          {
              client.Send(mailMessage);
          }
          catch{...}{
              //Error handling
          }
  
          client.Dispose();
  </code></pre>
  
  <p>Then I attempt to delete it:</p>
  
  <pre><code>File.Delete(HttpContext.Current.Server.MapPath("/Invoices/" + invoiceId + ".pdf"));
  </code></pre>