限制电子邮件发送过程的速度

2024-01-14

抱歉,标题有点蹩脚,我无法正确表达。

编辑:我应该注意到这是一个控制台 C# 应用程序

我已经设计出了一个像这样工作的系统原型(这是粗略的伪代码):

var collection = grabfromdb();

foreach (item in collection) {
    SendAnEmail();
}

发送电子邮件:

SmtpClient mailClient = new SmtpClient;
mailClient.SendCompleted += new SendCompletedEventHandler(SendComplete);
mailClient.SendAsync('the mail message');

发送完成:

if (anyErrors) {
    errorHandling()
}
else {
    HitDBAndMarkAsSendOK();    
}

显然这个设置并不理想。如果初始集合有 10,000 条记录,那么它将以相当短的顺序新建 10,000 个 smtpclient 实例,只要它能够逐步遍历行 - 并且可能会在此过程中爆炸。

我理想的最终结果是同时发出 10 封并发电子邮件。

我想到了一个 hacky 解决方案:添加一个计数器,当调用 SendAnEmail() 时该计数器递增,并在发送 SendComplete 时递减。在初始循环中调用 SendAnEmail() 之前,检查计数器,如果计数器太高,则休眠一小段时间,然后再次检查。

我不确定这是一个好主意,并且认为蜂巢思维会有办法正确地做到这一点。

我对线程知之甚少,不确定它是否适合在这里使用。例如,在后台线程中发送电子邮件,首先检查子线程的数量,以确保没有使用太多子线程。或者是否内置某种类型的“线程限制”。


Update

根据 Steven A. Lowe 的建议,我现在有:

  • 包含我的电子邮件和唯一密钥的字典(这是电子邮件队列
  • FillQue 方法,用于填充字典
  • ProcessQue 方法,它是一个后台线程。它检查队列,并发送队列中的任何电子邮件。
  • SendCompleted 委托,用于从队列中删除电子邮件。并再次调用 FillQue。

我对这个设置有一些问题。我想我错过了后台线程的船,我应该为字典中的每个项目生成其中一个吗?如果电子邮件队列清空线程结束,我怎样才能让线程“徘徊”,因为缺乏更好的词。


最终更新

我在后台线程中放置了一个“while(true) {}”。如果队列为空,它将等待几秒钟并重试。如果队列反复为空,我会“中断”该时间,然后程序结束......工作正常。不过,我有点担心“while(true)”业务。


简答

使用队列作为有限缓冲区,由其自己的线程处理。

长答案

调用 fill-queue 方法来创建电子邮件队列,限制为(例如)10 封。用前 10 封未发送的电子邮件填充该队列。启动一个线程来处理队列 - 对于队列中的每封电子邮件,异步发送。当队列为空时,休眠一段时间,然后再次检查。让完成委托从队列中删除已发送或有错误的电子邮件并更新数据库,然后调用 fill-queue 方法将更多未发送的电子邮件读入队列(备份到限制)。

您只需要围绕队列操作进行锁定,并且只需管理(直接)一个线程来处理队列。您永远不会同时有超过 N+1 个线程处于活动状态,其中 N 是队列限制。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

限制电子邮件发送过程的速度 的相关文章

随机推荐