为什么异步发送许多电子邮件会阻塞网站?(使用Action.BeginVoke)

本文关键字:网站 使用 Action BeginVoke 异步 许多 电子邮件 为什么 | 更新日期: 2023-09-27 18:21:37

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

使用: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对吗?

为什么异步发送许多电子邮件会阻塞网站?(使用Action.BeginVoke)

这个代码有很多错误:

  1. 你的试跳拦截很奇怪。您正在处理中的对象一次迭代,但它可以被其他迭代使用。请尝试使用块
  2. 执行asp.net请求的时间最长
  3. 不要在asp.net中设置线程睡眠
  4. 是的,asp.net池中有一个最大线程数

如果你最终因为一个原因被阻止,你也可能被会话阻止(如果你有)。。。如果你打开不同的浏览器,它能工作吗?

您正在启动一大堆要在线程池中执行的操作。线程池将创建最大数量的线程,之后发送到池的工作项只需排队即可。由于线程池中充斥着太多操作,因此线程池无法有机会处理ASP.NET为处理页面而添加的项。由于静态项不需要将工作推送到线程池,因此可以为这些项提供服务。

你不应该同时发射这么多项目。您应该将并行度限制在一个相当小的固定量。让每个启动的少数项目处理大量的操作,这样线程池中的线程也有可能处理其他事情。

我们定期发送10000封客户电子邮件。我将电子邮件的所有详细信息存储在数据库中,然后调用网络服务发送。这只是在他们身上颠簸,对其他任何事情都没有影响。我确实在每次调用Send之间让线程睡眠(在web服务中)100毫秒。。。如果我不这样做,那么大量的电子邮件似乎会淹没我们的邮件服务器,我们会发生一些奇怪的事情。