抱歉标题有点糟糕,我无法准确表达。
编辑:我应该指出这是一个控制台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()时递增,并在发送完成后递减。在初始循环中调用SendAnEmail()之前,检查计数器,如果太高,则休眠一小段时间,然后再次检查。
我不确定这是个好主意,希望SO的人们能够给出解决方法。
我对线程的了解很少,不确定在这里是否可以使用。例如,在后台线程中发送电子邮件,首先检查子线程的数量,以确保没有使用太多。或者是否有内置的“线程限制”类型。
更新
根据Steven A. Lowe的建议,我现在有:
- 一个包含我的电子邮件和唯一键的字典(这是电子邮件队列) - 一个填充队列的方法 - 一个处理队列的方法,它是一个后台线程。它检查队列,并异步发送任何在队列中的电子邮件。 - 一个SendCompleted委托,它从队列中删除电子邮件。然后再次调用FillQue。
我对这个设置有一些问题。我认为我错过了后台线程所需要的,我应该为字典中的每个项目生成一个后台线程吗?如果电子邮件队列为空,如何让线程“挂起”,不继续执行?
最终更新
我在后台线程中放了一个“while(true){}”。如果队列为空,它会等待几秒钟并重试。如果队列反复为空,我会“break”这个while,程序就会结束...工作得很好。但是我有点担心“while(true)”这个东西...