为什么发送许多电子邮件异步阻止该网站? (使用Action.BeginInvoke)

时间:2014-09-11 19:29:44

标签: c# asp.net iis-6 begininvoke

我创建了一个页面,向我们的客户发送了数千封电子邮件,几乎是8K封电子邮件。 发送过程需要几个小时,但过了一段时间我无法访问托管页面的站点中的任何页面(等待...),静态文件除外(图像等等)。

使用:IIS 6和.Net 4.0

代码:

public static bool Send(MailSettings settings, Action<string, string[], bool> Sent = null)
{
  System.Net.Mail.SmtpClient client; 
...
  foreach(){
    try{ client.Send(message);}catch{...client.Dispose();...}
    Sent.BeginInvoke(stringValue, stringArray, boolValue, null, null);
    if(count++>N){
       count=1;
       System.Threading.Thread.Sleep(1000);
    }
  }
...
}

public void SentComplete(string email, string[] value, bool isSent)
{
   ....//DB logging
}
  • 注意:使用相同应用程序池的其他站点都没问题!

问题:

  • 同一网站的线程数是否有IIS 6.0限制?

  • 如果我的代码导致任何性能问题,有什么想法?我正在使用Action吗?

3 个答案:

答案 0 :(得分:2)

这段代码有很多问题:

  1. 你的try catch块非常奇怪。你正在处理一个对象 一次迭代,但也可以被其他人使用。请尝试使用块。
  2. asp.net请求有最长时间执行。
  3. 不要把线程睡眠放在asp.net!
  4. 是的,asp.net池中有一个最大线程数
  5. 如果由于某种原因导致阻止,您也可能被会话阻止(如果有的话)...如果您打开其他浏览器,它是否有效?

答案 1 :(得分:1)

你要解决一大堆要在线程池中执行的操作。线程池将创建最大线程数,之后发送到池的工作项将排队等候。由于您使用如此多的操作充斥线程池,因此您阻止线程池有机会处理ASP.NET添加的项目以处理页面。由于静态项不需要将工作推送到线程池,因此可以对这些项进行维护。

你不应该同时开除这么多项目。您应该将并行度限制为相当小的固定量。让你开始的那些少数项目处理大量的操作,以便线程池中的线程也可以处理其他事情。

答案 2 :(得分:0)

我们会定期发送10000封客户电子邮件。我将电子邮件的所有详细信息存储在数据库中,然后调用Web服务发送它们。这只是通过它们而不会影响其他任何东西。我确实让线程在每次调用Send之间睡眠(在Web服务中)持续100ms ...如果我不这样做,那么很多电子邮件似乎压倒了我们的邮件服务器,我们发生了一些奇怪的事情。< / p>