我正在尝试从ASP.NET MVC 4 Web应用程序向客户发送500封电子邮件。我只是使用类似下面的foreach循环。大约50个周期后,我得到一个通用异常,说无法发送邮件。我相信我正在处理限制我的Web应用程序的限制和 MS Exchange设置。如何简单地实施限制以绕过这些限制?
感谢。
foreach (var toAddress in addresses)
{
var message = new MailMessage(fromAddress, toAddress)
{
Subject = subject,
Body = body
};
message.IsBodyHtml = isHtml;
try
{
using (var client = new SmtpClient())
{
client.Send(message);
}
}
catch (Exception ex)
{
Debug.WriteLine("Cannot send e-mail to " + message.To + Environment.NewLine +
"Subject: " + subject + Environment.NewLine +
"Body: " + body + Environment.NewLine +
"Exception: " + ex.Message);
}
}
答案 0 :(得分:2)
我会查看Quartz.NET并使用服务发送电子邮件。就排队而言,可能会查看简单的文件存储或数据库。
如果您使用类似Thread.Sleep
的内容,请记住,您将从呈现最终输出中阻止服务器(例如,如果通过表单提交触发,则生成的视图将不会显示电子邮件已发送)。通过使用像quartz这样的库,您可以在卸载电子邮件发送时保持服务器对请求的响应。
此外,作为参考,还有另一篇关于在不拖动UX的情况下执行昂贵操作的帖子。这可以找到here,{IMHO}是TheCodeKing最相关的答案。
答案 1 :(得分:1)
如果您使用的是Exchange 2010或更高版本,则会有一个RecipientRateLimit限制策略参数,该参数指定用户可以在24小时内处理的收件人数限制。如果您想要绕过此限制,则需要更改发送这些消息的用户的限制策略,请参阅http://www.slipstick.com/exchange/limit-number-of-internet-messages-user-can-send/
干杯 格伦
答案 2 :(得分:0)
我们的场景是使用本地MS Exchange Server 2010的远程Web应用程序,目前唯一可行的解决方案如下。每10秒钟使用20-30条消息块,我可以向客户发送我想要的自定义电子邮件数量,而无需触及MS Exchange Sever 2010配置(需要数小时的培训)。此外,所有内容都记录在TXT文件中,以确保实际发送消息。我还建议使用MS Exchange Tracking Log Explorer工具来检查是否发送了哪些消息。
private void SendBulkEmail(List<KeyValuePair<Customer, Order>> customerList, MailAddress sender, string subject, string body, bool isHtml, string fileNamePrefix)
{
const int chunkSize = 20;
string rootPath = Server.MapPath("~");
string path = Path.GetFullPath(Path.Combine(rootPath, "Logs"));
string fileName = CommonUtils.GetLogFileName(path, fileNamePrefix);
int len = customerList.Count;
TextWriter tw = new StreamWriter(fileName);
int chunkCount = (len / chunkSize) + 1;
int remainder = len % chunkSize;
for (int j = 0; j < chunkCount; j++)
{
int start = j * chunkSize;
int end = start + chunkSize;
if (j == chunkCount - 1)
{
end = start + remainder;
}
SmtpClient client = new SmtpClient();
for (int i = start; i < end; i++)
{
Customer customer = customerList[i].Key;
Guid userGuid = new Guid(customer.UserId.ToString());
MembershipUser membershipUser = Membership.GetUser(userGuid);
string memberUsername = membershipUser.UserName;
string memberEmail = membershipUser.Email;
SendMessage(sender, recipient, subject, body, tw, client, context);
}
client.Dispose();
Thread.Sleep(10000); // 10 seconds
tw.WriteLine("Completed chunk #" + j);
}
tw.Close();
}
public static void SendEmail(MailAddress fromAddress, MailAddress toAddress, string subject, string body, TextWriter tw, SmtpClient smtpClient)
{
MailMessage message = new MailMessage(fromAddress, toAddress)
{
Subject = subject,
Body = body
};
try
{
smtpClient.Send(message);
if (tw != null)
{
tw.WriteLine("\"" + toAddress + "\",");
}
}
catch (Exception ex)
{
if (tw != null)
{
tw.WriteLine(toAddress + ": " + ex.Message + " " + ex.InnerException.Message);
}
Debug.WriteLine("Cannot send e-mail to " + toAddress + ", " + "Exception: " + ex.Message + (ex.InnerException != null ? ", " + ex.InnerException.Message : string.Empty));
}
}