[英]Send bulk email with MailKit in C#
我们正在使用MailKit
通过创建客户端,建立连接和发送邮件来成功发送电子邮件。 非常标准的东西非常有用,因为我们在应用程序中收到一条消息,然后做一些事情并通过电子邮件发送。
但是,我们希望能够尽快处理成千上万的电子邮件 。
我们的目标电子邮件服务器可能不可用,因此我们可以快速备份邮件,从而产生积压。
使用MailKit
,最好的和最快捷的方式是处理邮件,以便尽快发送邮件。 例如,此刻每个邮件可能一个接一个地处理,如果每个处理都花费一秒钟,则可能要花费很长时间才能发送40000封邮件。
我们一直在使用parallel foreach
来启动许多线程,但这有其局限性。 任何建议或建议,将不胜感激。
已添加代码示例: 更正,已添加新代码示例。 这要快得多,但是每次都无法使它工作以创建新的连接。 Exchange引发错误“已指定发件人”。 目前,平均每秒大约发送6封邮件。
var rangePartitioner = Partitioner.Create(0, inpList.Count, 15);
var po = new ParallelOptions { MaxDegreeOfParallelism = 30 };
Parallel.ForEach(rangePartitioner, (range, loopState) =>
{
using (var client = new SmtpClient(new SlabProtocolLogger()))
{
client.Connect(_appSettings.RelayAddress, _appSettings.RelayPort);
client.AuthenticationMechanisms.Remove("XOAUTH2");
for (int i = range.Item1; i < range.Item2; i++)
{
var message = _outboundQueueRepository.Read(inpList[i]).Load();
client.Send(message.Body, message.Metadata.Sender, message.Metadata.Recipients.Select(r => (MailboxAddress)r));
_outboundQueueRepository.Remove(inpList[i]);
};
}
});
如果我错了,请纠正我,但是在我看来,这种工作方式是Parallel.Foreach正在创建一定数量的线程。 然后,每个线程都会创建一个SMTP连接,然后循环发送一批消息。
这对我来说似乎很合理。
我可以提供给您的唯一建议可能会进一步优化此建议,即如果这些邮件中的许多邮件具有完全相同的内容和相同的“发件人”地址,并且唯一的区别是收件人是谁,则可以大大减少所需的邮件数量发送。
例如,如果您当前正在执行以下操作,例如发送以下3条消息:
讯息1:
From: no-reply@company.com
To: Joe The Plumber <joe@plumbing-masters.com>
Subject: We've got a new sale! 50% off everything in stock!
some message text goes here.
讯息2
From: no-reply@company.com
To: Sara the Chef <sara@amazing-chefs.com>
Subject: We've got a new sale! 50% off everything in stock!
some message text goes here.
讯息3:
From: no-reply@company.com
To: Ben the Cobbler <ben@cobblers-r-us.com>
Subject: We've got a new sale! 50% off everything in stock!
some message text goes here.
您的代码可能会创建3个线程,并在每个线程中发送一条消息。
但是,相反,如果您创建了以下一条消息,该怎么办:
From: no-reply@company.com
To: undisclosed-recipients:;
Subject: We've got a new sale! 50% off everything in stock!
some message text goes here.
然后使用以下代码通过同一MimeMessage
发送给所有3个客户?
var sender = new MailboxAddress (null, "no-reply@company.com");
var recipients = new List<MailboxAddress> ();
recipients.Add (new MailboxAddress ("Joe the Plumber", "joe@plumbing-masters.com"));
recipients.Add (new MailboxAddress ("Sara the Chef", "sara@amazing-chefs.com"));
recipients.Add (new MailboxAddress ("Ben the Cobbler", "ben@cobblers-r-us.com"));
client.Send (message, sender, recipients);
您的所有3个客户都将收到同一封电子邮件,您不必发送3条消息,只需要发送1条消息即可。
您可能已经了解了这个概念,所以这可能根本对您没有帮助-我只是提到它,因为我注意到这并不是每个人都立即意识到的。 有些人认为他们需要向每个收件人发送1条消息,因此最终导致他们实际上只需要发送1条消息时就尝试优化发送1000条消息。
因此,我们发现了范围更广的修复程序,除了通过Parrallel ForEach循环发现的改进之外,还大大提高了性能。 与MailKit无关,但我想还是应该分享。 调用代码创建inputList的方式是使用DirectoryInfo.GetDirectories枚举目录中的所有第一个。 在某些情况下,我们的代码需要2秒钟才能在其中包含40k文件的目录上执行。 我们将其更改为EnumerateDirectories,它有效地释放了邮件发送代码以发送许多电子邮件。
因此可以确认,并行循环非常有效,其他地方的根本性能问题是真正的瓶颈。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.