我正在尝试设计一个多线程Windows应用程序,主要是为我们的客户快速发送电子邮件给他们的客户(因为有一家大型电信公司可能有数百万),我需要设计提示。(对不起,Q很长)
我公平地阅读了有关多线程应用程序的文章。我还阅读了有关SmartThread池,.NET ThreadPool,任务并行库和其他SO问题的内容。但我无法提供正确的设计。我的逻辑就是这样:
在程序开始时(电子邮件引擎),计时器启动并检查数据库(广告系列表)中是否有任何具有状态1(新广告系列)的电子邮件广告系列。
如果有,则应从数据库中查询Campaign订阅者,并将其写入名为SubscriberReports表的另一个表(SqlBulkCopy),并在Campaignigns表中将Campaign的状态更新为2.
计时器还会侦听状态为2的广告系列,以调用另一种方法为每个订阅者自定义广告系列,创建一个具有订阅者自定义属性的Struct。
第三,调用SendEmail方法通过SMTP发送电子邮件。我到目前为止尝试的是下面的内容(我知道ThreadPool在这里是错的,我还有很多其他的错误)。你能不能建议并帮助我如何设计这样的应用程序。非常感谢任何帮助。非常感谢您的时间。
private void ProcessTimer(object Source, ElapsedEventArgs e)
{
Campaigns campaign = new Campaigns();
IEnumerable<Campaigns> campaignsListStatusOne = // Get Campaign Properties to a List
IEnumerable<Campaigns> campaignsListStatusTwo = // Get Campaign Properties to a List
foreach (Campaigns _campaign in campaignsListStatusOne)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(CheckNewCampaign), _campaign.CampaignID);
}
foreach (Campaigns _campaign in campaignsListStatusTwo)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(CustomizeMail), _campaign.CampaignID);
}
}
private void CheckNewCampaign(object state)
{
int campaignID = (int)state;
DataTable dtCampaignSubscribers = // get subscribers based on Campaign ID
campaign.UpdateStatus(campaignID, 2);
}
private void CustomizeMail(object state)
{
int campaignID = (int)state;
CampaignCustomazition campaignCustomizer;
IEnumerable<SubscriberReports> reportList = // get subscribers to be sent from Reports table
foreach (SubscriberReports report in reportList)
{ // 3 database related methods are here
campaignCustomizer = new CampaignCustomazition(report.CampaignID, report.SubscriberID);
campaignCustomizer.CustomizeSource(report.CampaignID, report.SubscriberID, out campaignCustomizer.source, out campaignCustomizer.format);
campaignCustomizer.CustomizeCampaignDetails(report.CampaignID, report.SubscriberID, out campaignCustomizer.subject, out campaignCustomizer.fromName, out campaignCustomizer.fromEmail, out campaignCustomizer.replyEmail);
campaignCustomizer.CustomizeSubscriberDetails(report.SubscriberID, out campaignCustomizer.email, out campaignCustomizer.fullName);
ThreadPool.QueueUserWorkItem(new WaitCallback(SendMail), campaignCustomizer);
}
}
private void SendMail(object state)
{
CampaignCustomazition campaignCustomizer = new CampaignCustomazition();
campaignCustomizer = (CampaignCustomazition)state;
//send email based on info at campaignCustomizer via SMTP and update DB record if it is success.
}
答案 0 :(得分:3)
使用线程在这里几乎无法获得。什么线程给你买的是更多的cpu周期。假设您拥有一台具有多个内核的计算机,这些天非常标准。但这并不是你需要更快地完成工作所需要的。您需要更多dbase和电子邮件服务器。当然你只有一个。您的程序将刻录非常小核心,它会不断等待dbase查询和电子邮件服务器完成其工作。
获得成功的唯一方法是重叠每个的延迟。一个线程可能一直在等待dbase引擎,另一个线程可能一直在等待电子邮件服务器。哪个比等待两者的线程更好。
不过,这也不太可能让你买得太多,两者之间存在很大的不匹配。 dbase引擎可以在一秒钟内为您提供数千个电子邮件地址,电子邮件服务器每秒只能发送几百封电子邮件。一切都受到电子邮件服务器工作速度的限制。
鉴于获得成功的可能性很小,我建议你不要试图让线程陷入困境。如果你没有正确锁定,它有一个很难诊断失败的诀窍。您可以花费大量时间进行故障排除,这可能会大大超过移动速度的操作收益。
如果您正在考虑线程以避免冻结用户界面,那么这是合理的线程使用。使用BackgroundWorker。 MSDN Library对它有很好的帮助。