我正在尝试异步发送带有附件的电子邮件。这些附件是动态生成的并保存到服务器,因此我想在发送电子邮件后删除它们。
下面的代码成功发送电子邮件,但是之后整个站点被锁定。我只能假设它无法删除已附加到电子邮件的生成文件,不会抛出任何错误,也不会发布任何日志。我知道文件路径是正确的,因为使用相同的路径将文件附加到电子邮件中。注意:我正在释放邮件和附件对象。
在我的开发环境中一切正常,但在生产环境中则不然。应该注意的是,此代码是从放置在网站 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 集合类不提供任何线程同步;在多个线程上同时添加或删除项时,用户代码必须提供所有同步。
点击此处查看全文