电子邮件发送过程的节流调速 [英] Throttling speed of email sending process

查看:192
本文介绍了电子邮件发送过程的节流调速的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对不起标题是有点蹩脚,我可以适当不太字呢

Sorry the title is a bit crappy, I couldn't quite word it properly.

编辑:我要指出,这是一个控制台C#应用程序

I should note this is a console c# app

我已经试制出来的作品像这样的系统(这是粗糙的伪codeish):

I've prototyped out a system that works like so (this is rough pseudo-codeish):

var collection = grabfromdb();

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



SendAnEmail:

SendAnEmail:

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



SendComplete:

SendComplete:

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



显然这种设置并不理想。如果最初的收藏有,说10000条记录,然后它会smtpclient新注册10000实例相当短为了尽可能快,因为它可以通过行一步 - 而且可能asplode在这个过程中

Obviously this setup is not ideal. If the initial collection has, say 10,000 records, then it's going to new up 10,000 instances of smtpclient in fairly short order as quickly as it can step through the rows - and likely asplode in the process.

我理想中的最后一步就是有一些像10个并发电子邮件走出去一次

My ideal end game is to have something like 10 concurrent email going out at once.

一个哈克解决方案浮现在脑海:添加计数器,这当发送SendComplete递增时SendAnEmail()被调用,并且递减。 SendAnEmail()被调用在最初的循环之前,检查计数器,如果它是太高,那么睡眠的一小段时间,然后重新检查。

A hacky solution comes to mind: Add a counter, that increments when SendAnEmail() is called, and decrements when SendComplete is sent. Before SendAnEmail() is called in the initial loop, check the counter, if it's too high, then sleep for a small period of time and then check it again.

我不敢肯定这是个好主意,而图中的SO蜂巢的脑海里有一个方法正确地做到这一点。

I'm not sure that's such a great idea, and figure the SO hive mind would have a way to do this properly.

我有线程和没有把握的非常小知识如果它会在这里的适当使用。如发送电子邮件在后台线程,首先检查孩子的线程数,以确保有正在使用的不是太多。或者,如果有某种类型的内置的线程节流的。

I have very little knowledge of threading and not sure if it would be an appropriate use here. Eg sending email in a background thread, first check the number of child threads to ensure there's not too many being used. Or if there is some type of 'thread throttling' built in.


在史蒂芬A.洛的建议之后,我现在有:

Following in the advice of Steven A. Lowe, I now have:


  • 词典握着我的电子邮件和唯一的密钥(这是电子邮件阙

  • 系统FillQue方法,其中填充字典

  • 系统ProcessQue方法,是一个后台线程,它会检查阙,并SendAsycs任何电子邮件中的阙。

  • 系统SendCompleted委托,再次将删除阙的电子邮件。并呼吁FillQue。

  • A Dictionary holding my emails and a unique key (this is the email que
  • A FillQue Method, which populates the dictionary
  • A ProcessQue method, which is a background thread. It checks the que, and SendAsycs any email in the que.
  • A SendCompleted delegate which removes the email from the que. And calls FillQue again.

我有一些问题与此设置。我想我已经错过了船与后台线程,我应该产卵其中之一为每在字典中的项目?我怎样才能得到线程流连由于缺乏一个更好的词,如果电子邮件阙清空线头。

I've a few problems with this setup. I think I've missed the boat with the background thread, should I be spawning one of these for each item in the dictionary? How can I get the thread to 'hang around' for lack of a better word, if the email que empties the thread ends.


我把一个',而(真){}'在后台线程如果阙是空的,它会等待几秒钟,然后再次尝试。如果阙反复空,我突破的同时,程序结束...工作正常。我有点担心,而(真)的业务,但..

I've put a 'while(true) {}' in the background thread. If the que is empty, it waits a few seconds and tries again. If the que is repeatedly empty, i 'break' the while, and the program ends... Works fine. I'm a bit worried about the 'while(true)' business though..

推荐答案

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

Short Answer

Use a queue as a finite buffer, processed by its own thread.

,呼叫填充队列的方法来创建的电子邮件的一个队列中,不限于(比方说)10与第一10未发送邮件填充它。启动一个线程来处理队列 - 队列中的每封电子邮件,发送非同步。当队列为空时睡眠,并再次检查。具有完成委托从队列中删除已发送或差错电子邮件,更新数据库,然后调用填充队列方法来读取更多的未发送邮件到队列(备份到极限)。

Call a fill-queue method to create a queue of emails, limited to (say) 10. Fill it with the first 10 unsent emails. Launch a thread to process the queue - for each email in the queue, send it asynch. When the queue is empty sleep for a while and check again. Have the completion delegate remove the sent or errored email from the queue and update the database, then call the fill-queue method to read more unsent emails into the queue (back up to the limit).

您只需要围绕队列操作锁,并且只需要管理(直接)的一个线程来处理队列中。你将永远不会有比主动N + 1多线程一次,其中N是队列限制。

You'll only need locks around the queue operations, and will only have to manage (directly) the one thread to process the queue. You will never have more than N+1 threads active at once, where N is the queue limit.

这篇关于电子邮件发送过程的节流调速的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆