gpt4 book ai didi

asp.net - 防止多线程网站消耗过多资源

转载 作者:行者123 更新时间:2023-12-02 15:20:43 25 4
gpt4 key购买 nike

我为客户建立了一个批量电子邮件发送网站,需要一次发送 80,000 封电子邮件。它基本上为发送创建一个新线程,以便可以将控制权交还给 UI(以便可以加载反馈页面),然后为每个公司创建一个新线程,以便将电子邮件发送给收件人。所有电子邮件均使用以下代码排队:

// 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 中或通过更改上面的代码来限制发送应用程序的资源使用?

最佳答案

问题:

  • 您正在 Parallel ForEach 内部生成一个线程,“Parallel”部分意味着它已经为主体生成了一个线程。您正在将 Parallel Invoke 而不是 Action 嵌套在另一个 Action 的 Parallel ForEach 中。

  • 您正在线程内运行 while 循环,CPU 没有休息。这就是并行调用 5 次。

答案:

对于 CPU 使用情况,您需要让处理休息一下。在您的 While TryDequeue 循环中放置一个短暂的 sleep 。

        MailMessage message;
while (queue.TryDequeue(out message))
{
SendMessage(sendingServer, message, factory);
Thread.Sleep(16);
}

对于 RAM 和 CPU 使用情况,您需要立即处理 LESS。

        SendingThread = Task.Factory.StartNew(() =>
{
foreach(var company in companies)
{
// 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);


}
}, new CancellationToken(), TaskCreationOptions.LongRunning, TaskScheduler.Default);

关于asp.net - 防止多线程网站消耗过多资源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9630813/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com