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