System.Net.Mail 的性能问题
我在从我的应用程序发送邮件时遇到了这个不寻常的问题。起初它不起作用(无法转发错误废话)无论如何我添加了正确的身份验证并且它起作用了。我现在的问题是,如果我尝试发送大约 300 封电子邮件(每封电子邮件都有 500k 附件),则应用程序在整个过程中将开始挂起大约 95%。
这是我的一些代码,我在想,每封要发送的邮件都会调用这些代码
Using mail As New MailMessage()
With mail
.From = New MailAddress(My.Resources.EmailFrom)
For Each contact As Contact In Contacts
.To.Add(contact.Email)
Next
.Subject = "Accounting"
.Body = My.Resources.EmailBody
'Back the stream up to the beginning orelse the attachment
'will be sent as a zero (0) byte file.
attachment.Seek(0, SeekOrigin.Begin)
.Attachments.Add(New Attachment(attachment, String.Concat(Item.Year, Item.AttachmentType.Extension)))
End With
Dim smtp As New SmtpClient("192.168.1.2")
With smtp
.DeliveryMethod = SmtpDeliveryMethod.Network
.UseDefaultCredentials = False
.Credentials = New NetworkCredential("username", "password")
.Send(mail)
End With
End Using
With item
.SentStatus = True
.DateSent = DateTime.Now.Date
.Save()
End With
Return
,我可以准备所有邮件并将它们添加到集合中,然后打开一个 SMTP 连接并迭代集合,像这样调用发送
Using mail As New MailMessage()
...
MailCollection.Add(mail)
End Using
...
Dim smtp As New SmtpClient("192.168.1.2")
With smtp
.DeliveryMethod = SmtpDeliveryMethod.Network
.UseDefaultCredentials = False
.Credentials = New NetworkCredential("username", "password")
For Each mail in MainCollection
.Send(mail)
Next
End With
I have this unusual problem with mailing from my app. At first it wasn't working (getting unable to relay error crap) anyways I added the proper authentication and it works. My problem now is, if I try to send around 300 emails (each with a 500k attachment) the app starts hanging around 95% thru the process.
Here is some of my code which is called for each mail to be sent
Using mail As New MailMessage()
With mail
.From = New MailAddress(My.Resources.EmailFrom)
For Each contact As Contact In Contacts
.To.Add(contact.Email)
Next
.Subject = "Accounting"
.Body = My.Resources.EmailBody
'Back the stream up to the beginning orelse the attachment
'will be sent as a zero (0) byte file.
attachment.Seek(0, SeekOrigin.Begin)
.Attachments.Add(New Attachment(attachment, String.Concat(Item.Year, Item.AttachmentType.Extension)))
End With
Dim smtp As New SmtpClient("192.168.1.2")
With smtp
.DeliveryMethod = SmtpDeliveryMethod.Network
.UseDefaultCredentials = False
.Credentials = New NetworkCredential("username", "password")
.Send(mail)
End With
End Using
With item
.SentStatus = True
.DateSent = DateTime.Now.Date
.Save()
End With
Return
I was thinking, can I just prepare all the mails and add them to a collection then open one SMTP conenction and just iterate the collection, calling the send like this
Using mail As New MailMessage()
...
MailCollection.Add(mail)
End Using
...
Dim smtp As New SmtpClient("192.168.1.2")
With smtp
.DeliveryMethod = SmtpDeliveryMethod.Network
.UseDefaultCredentials = False
.Credentials = New NetworkCredential("username", "password")
For Each mail in MainCollection
.Send(mail)
Next
End With
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您遇到的限制很可能是由 SMTP 服务器而不是您的代码强制执行的。
SMTP 服务器很容易受到垃圾邮件滥用,因此具有防止此类滥用的机制。
单独发送每封电子邮件并不总是有效,您正在与其他更复杂的机制竞争。
但从技术上讲,是的,您可以编写一段代码来单独发送它们。
The limitations you encounter are prolly enforced by the SMTP server, not your code.
SMTP servers are very prone to spam-abuse, and therefore have mechanisms to prevent such abuse.
Sending each email individually isn't always going to work, you're competing with other - more sophisticated - mechanisms.
But technically, yes, you can write a code that sends them individually.
对于您所说的大小和数量,我的建议是将它们放在 SMTP 可访问的文件夹中,并让 SMTP 服务器从该文件夹传送。这样会更快、更理智。
内存中的 500K 附件有点资源密集型,一次为 300 个附件分配 RAM 大约需要 200MB RAM(用于保留资源、每次创建新消息、打开库等的开销)。所以第二个问题是你的服务器可以处理这个问题吗?只是一个观察。
For the size and number you're talking about, my advice is to drop them on an SMTP accessible folder and let the SMTP server deliver from that folder. That'll be faster and saner.
500K attachments in memory are kinda resource intensive, and allocating RAM for 300 at a pop is roughly 200MB RAM (overhead for holding onto resources, creating a new message each time, opening libraries, etc). So a second question is can your server handle this? Just an observation.