对不起,标题有点糟糕,我无法正确地说出来.
编辑:我应该注意这是一个控制台c#app
我已经制作了一个像这样工作的系统原型(这是粗略的伪代码):
var collection = grabfromdb(); foreach (item in collection) { SendAnEmail(); }
发送电子邮件:
SmtpClient mailClient = new SmtpClient; mailClient.SendCompleted += new SendCompletedEventHandler(SendComplete); mailClient.SendAsync('the mail message');
SendComplete:
if (anyErrors) { errorHandling() } else { HitDBAndMarkAsSendOK(); }
显然这种设置并不理想.如果初始集合有10,000个记录,那么它将以相当短的顺序刷新10,000个smtpclient实例,因为它可以逐步执行 - 并且可能在此过程中呈现.
我理想的最终游戏是同时发送10个并发电子邮件.
想到一个hacky解决方案:添加一个计数器,在调用SendAnEmail()时递增,并在发送SendComplete时递减.在初始循环中调用SendAnEmail()之前,检查计数器,如果它太高,则在一段时间内休眠,然后再次检查.
我不确定这是一个如此伟大的想法,并认为SO蜂巢的思想将有办法正确地做到这一点.
我对线程知之甚少,不确定它是否适合在这里使用.例如,在后台线程中发送电子邮件,首先检查子线程的数量,以确保没有太多使用.或者如果内置了某种类型的"线程限制".
根据Steven A. Lowe的建议,我现在有:
一个字典,包含我的电子邮件和一个唯一的密钥(这是电子邮件队列
填充字典的FillQue方法
ProcessQue方法,它是后台线程.它检查que和SendAsycs中的任何电子邮件.
SendCompleted委托,用于从que中删除电子邮件.并再次调用FillQue.
我对这个设置有一些问题.我想我已经错过了背景线程的船,我是否应该为词典中的每个项目产生其中一个?如果电子邮件que清空线程结束,我怎么能让线程因为缺少更好的单词而"闲逛".
我在后台线程中放了一个'while(true){}'.如果que为空,则等待几秒钟并再次尝试.如果阙重复为空,我'打破'一会儿,程序结束......工作正常.我有点担心'虽然(真)'的业务但是......