Deleting MailMessage attachments causes website to hang

60 views Asked by At

I am attempting to send an email asynchronously that has attachments. These attachments are generated on the fly and saved to the server, so I would like to delete them after the email has been sent.

The code below is successful in sending the email, however the whole site locks up afterwards. I can only assume that it cannot delete the generated file that has been attached to the email, no errors are thrown and no logs are posted. I know the file path is correct, as the same path is being used to attach the file to the email. Note I am disposing the Message and Attachment objects.

Everything works fine in my development environment, but not on production. It should be noted that this code is being executed from a .dll that is placed in the bin folder of the website.

ThreadStart starter = delegate { SendAsync(ref message, Attachments, Settings); };
Thread thread = new Thread(starter);
thread.IsBackground = true;
thread.Start();

private static void SendAsync(ref MailMessage Message, List<clsEmailAttachment> Attachments, clsSmtpSettings Settings)
{
    try
    {
        SmtpClient smtp = new SmtpClient();
        smtp.Host = Settings.Host;
        NetworkCredential Credential = new NetworkCredential(Settings.Username, Settings.Password, Settings.Domain);
        smtp.UseDefaultCredentials = false;
        smtp.Credentials = Credential;
        smtp.DeliveryMethod = SmtpDeliveryMethod.Network;
        smtp.Send(Message);
    }
    catch (Exception SendingEmailException)
    {
        Log.PostLog(null, 4007, SendingEmailException.Message);
    }
    finally
    {
        try
        {
            Message.Attachments.Dispose();
            Message.Dispose();
            foreach (clsEmailAttachment attachment in Attachments)
            {
                if (attachment.Delete == true)
                {
                    try
                    {
                        File.Delete(attachment.Path);
                    }
                    catch { throw; }
                }
            }
        }
        catch (Exception DeletingAttachmentsException)
        {
            Log.PostLog(null, 4008, DeletingAttachmentsException.Message);
        }
    }
}
1

There are 1 answers

0
Jack Pettinger On BEST ANSWER

After much trial and error I have solved the problem. It turns out to be a multi-threading issue with the Attachments collection. The following is being called on a new thread:

private static void SendAsync(ref MailMessage Message, List<clsEmailAttachment> Attachments, clsSmtpSettings Settings)

Generic.List<type> is not a threadsafe collection. The following statement is taken from the msdn:

The collection classes introduced in the .NET Framework 2.0 are found in the System.Collections.Generic namespace. These include List, Dictionary, and so on. These classes provide improved type safety and performance compared to the .NET Framework 1.0 classes. However, the .NET Framework 2.0 collection classes do not provide any thread synchronization; user code must provide all synchronization when items are added or removed on multiple threads concurrently.

See here for the Full article