我已经为客户端构建了一个批量电子邮件发送网站,该客户端需要在单个发送中发送80,000封电子邮件。它基本上为发送创建了一个新线程,以便控制权可以交还给用户界面(这样可以加载反馈页面),然后为每个公司创建一个新线程,以便将电子邮件发送给收件人。这些电子邮件都排队,使用此代码:防止多线程网站消耗太多资源
// Loop through the companies and send their mail to the specified recipients
// while creating a new thread for each company
// A new thread is started so that the feedback page can load
SendingThread = Task.Factory.StartNew(() =>
{
// This is a thread safe for loop
Parallel.ForEach<CompanyEntity>(companies, company =>
{
// Start a new thread for each company send
Task.Factory.StartNew(() =>
{
// Get the recipients for this company
var companyRecipients = GetSubscribersForCompany(company.Id, recipients);
// Send the newsletter to the company recipients
var success = SendNewsletterForCompany(newsletter, company, companyRecipients, language,
version, company.AdvertCollectionViaNewsletterCompanyAdvertLink, newsletter.NewsletterType, email);
// Add the status update so the front end can view a list of updated conpany statuses
if (success)
AddStatusUpdate(company.CompanyTitle + " has completed processing.");
// Starts sending the emails if the engine hasn't already been started
SendEngine.Start(CurrentSmtpClient, this);
}).ContinueWith(antecendent => EndCompaniesSendUpdate(companiesToProcess, companiesProcessed), TaskContinuationOptions.OnlyOnRanToCompletion);
});
}, new CancellationToken(), TaskCreationOptions.LongRunning, TaskScheduler.Default);
虽然电子邮件排队,发送引擎接管并从队列中拉电子邮件,然后使用新的Parallel类并将它们发送:
Action action =() =>
{
MailMessage message;
while (queue.TryDequeue(out message))
{
SendMessage(sendingServer, message, factory);
}
};
// Start 5 concurrent actions to send the messages in parallel.
Parallel.Invoke(action, action, action, action, action);
所有这些都很棒,可以在10分钟内发送40,000条新闻。唯一的问题是服务器上的RAM和CPU在这10分钟内100%被占用。这会影响服务器上的其他站点,因为它们无法访问。
有什么办法来限制IIS 7.5中发送应用程序的资源使用情况,或者通过更改上面的代码?
在网站的线程中初始化长时间运行的任务是错误的。这是Windows服务的用途。 – Stilgar 2012-03-09 08:27:19
我不知道你的队列通常是空的还是填充的,但是如果队列为空的话,一段时间(TryDequeue)循环会将内核的寿命从内核吸收掉。您是否有任何理由进行轮询,而不是在此队列上使用适当的信号? – 2012-03-09 09:17:43
@Stilgar不幸的是,我没有预算来重新开发它作为一个Windows服务,但我意识到,我应该看看这样做的前面。 – 2012-03-09 10:57:39