Удаление вложений MailMessage приводит к зависанию веб-сайта

Я пытаюсь асинхронно отправить электронное письмо с вложениями. Эти вложения генерируются на лету и сохраняются на сервере, поэтому я хотел бы удалить их после отправки электронного письма.

Приведенный ниже код успешно отправляет электронное письмо, однако после этого весь сайт блокируется. Я могу только предположить, что он не может удалить сгенерированный файл, прикрепленный к электронному письму, никаких ошибок и журналов не публикуется. Я знаю, что путь к файлу правильный, так как этот же путь используется для прикрепления файла к электронному письму. Примечание. Я удаляю объекты «Сообщение» и «Вложение».

В моей среде разработки все работает нормально, а в продакшене нет. Следует отметить, что этот код выполняется из .dll, который находится в папке bin веб-сайта.

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);
        }
    }
}

person Jack Pettinger    schedule 14.11.2014    source источник
comment
Вы пробовали его отлаживать? Каково значение attachment в цикле foreach?   -  person Ckrempp    schedule 14.11.2014


Ответы (1)


После долгих проб и ошибок я решил проблему. Оказывается, это проблема многопоточности с коллекцией вложений. В новом потоке вызывается следующее:

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

Generic.List<type> не является потокобезопасной коллекцией. Следующее утверждение взято из msdn:

Классы коллекций, представленные в .NET Framework 2.0, находятся в пространстве имен System.Collections.Generic. К ним относятся Список, Словарь и так далее. Эти классы обеспечивают повышенную безопасность типов и производительность по сравнению с классами .NET Framework 1.0. Однако классы коллекций .NET Framework 2.0 не обеспечивают никакой синхронизации потоков; пользовательский код должен обеспечивать всю синхронизацию при одновременном добавлении или удалении элементов в нескольких потоках.

См. здесь полную статью

person Jack Pettinger    schedule 18.11.2014