Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does SmtpClient.Send with attachments included hold a lock on the attached file?

I'm currently debugging an issue and couldn't find an answer to this question in the MSDN documentation

I have the following code:

if(attachmentFileName != null && File.Exists(attachmentFileName))
{
    mail.Attachments.Add(new Attachment(attachmentFileName, MediaTypeNames.Application.Octet));
}

using(SmtpClient smtp = new SmtpClient { UseDefaultCredentials = true })
{
    try
    {
        smtp.Send(mail);
    }
    catch(SmtpException ex)
    {
        if(attachmentFileName != null && ex.StatusCode == SmtpStatusCode.ExceededStorageAllocation)
        {
            //Need to still send the mail. Just strip out the attachment & add footer saying that attachment has been stripped out.
            mail.Attachments.Clear();
            mail.Body += "\n\nNote: Please note that due to outbound size limitations, attachments to this email have been stripped out.\n";
            smtp.Send(mail);
        }
        else
        {
            throw;
        }
    }
}

At a higher level (the caller of this method), I have the following:

try
{
    SendEmail(recipients, alertTitle, body, alertID, subjectPrefix, merchantIDValue, attachmentFilePath);
}
finally
{
    if(tempFile != null)
    {
        File.Delete(tempFile);
    }
}

I deployed the code to our test environment and I am now getting the following exception in our error logs:

System.IO.IOException: The process cannot access the file 'C:\fileName.zip' because it is being used by another process.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.File.Delete(String path)
   at AlertDelivery.CreateAttachmentFile(String attachmentData, String merchantID, String reportTitle) in d:\svn\trunk\Solution\Alerting\AlertDelivery.cs:line 143
   at AlertDelivery.TrySendAlert(String merchantID, String reportTitle, Int32 alertID, String alertTitle, String attachmentData, String attachmentFilePath, String body, Boolean isReport, String subjectPrefix, List`1 recipients) in d:\svn\trunk\Solution\Alerting\AlertDelivery.cs:line 110
   at AlertingService.ProcessAlertEvents(Object parameters) in d:\svn\trunk\Solution\Alerting\AlertingService.cs:line 174

Line 174 is the File.Delete(tempFile); line in the caller code.

Does SmtpClient maintain an asynchronous lock on attachments after SmtpClient.Send has been called? Any other conspicuous problems?

like image 370
Codeman Avatar asked Dec 04 '22 00:12

Codeman


1 Answers

Try to encapsulate your mail variable with a using statement
Something like this

public void SendEmail(...)
{
    using(MailMessage mail = new MailMessage())
    {

      .... your code above
    }

}

this will force the dispose call for the MailMessage object and that call also disposes any attachments.

like image 58
Steve Avatar answered Dec 31 '22 12:12

Steve