删除邮件附件会导致网站挂起



我正在尝试异步发送带有附件的电子邮件。这些附件是动态生成的并保存到服务器,因此我想在发送电子邮件后删除它们。

下面的代码成功发送电子邮件,但是之后整个站点被锁定。我只能假设它无法删除已附加到电子邮件的生成文件,不会抛出任何错误,也不会发布任何日志。我知道文件路径是正确的,因为使用相同的路径将文件附加到电子邮件中。注意:我正在释放邮件和附件对象。

在我的开发环境中一切正常,但在生产环境中则不然。应该注意的是,此代码是从放置在网站 bin 文件夹中的.dll执行的。

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

经过多次试验和错误,我已经解决了这个问题。事实证明,这是附件集合的多线程问题。正在新线程上调用以下内容:

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 集合类不提供任何线程同步;在多个线程上同时添加或删除项时,用户代码必须提供所有同步。

点击此处查看全文

最新更新