多线程Win窗体应用程序的设计模型和提示

本文关键字:模型 提示 Win 窗体 应用程序 多线程 | 更新日期: 2023-09-27 18:01:18

我正在尝试设计一个多线程的windows应用程序,主要为我们的客户快速发送电子邮件给他们的客户(有可能是数百万,因为有一个大的电信公司),我需要设计提示。(很抱歉Q太长了)

我读了很多关于多线程应用程序的文章。我还阅读了关于SmartThread Pool, . net ThreadPool, Task Parallel Library和其他SO问题。但是我不能带着一个正确的设计来。我的逻辑是这样的:

在程序(电子邮件引擎)开始时,计时器启动并检查数据库(活动表)中是否有状态为1(新活动)的电子邮件活动。

如果有,Campaign subscriber应该从DB中查询,并应该写入另一个名为SubscriberReports表的表(SqlBulkCopy),并在Campaigns表中将Campaign的Status更新为2。

Timer还监听状态为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.
 }

多线程Win窗体应用程序的设计模型和提示

在这里使用线程几乎没有什么好处。线程为您带来的是更多的cpu周期。假设你有一台多核的机器,这在现在很常见。但这并不是你更快完成工作所需要的。你需要更多的数据库和电子邮件服务器。你肯定只有一个。你的程序会燃烧非常小核心,它是不断等待数据库查询和电子邮件服务器完成他们的工作。

取得进展的唯一方法是重叠每个的延迟。一个线程可能一直在等待数据库引擎,另一个线程可能一直在等待电子邮件服务器。这比一个线程同时等待好。

这也不太可能给你买很多东西,这两者之间存在很大的不匹配。数据库引擎可以在一秒钟内为您提供数千个电子邮件地址,而电子邮件服务器一秒钟内只能处理几百封电子邮件。邮件服务器的工作速度决定了一切。

考虑到获得成功的几率很低,我建议你不要试图让自己陷入线程化的麻烦中。如果没有正确锁定,它会产生难以诊断的故障。您花在故障排除上的时间可能会大大超过移动快一点所带来的操作收益。

如果你正在考虑使用线程来避免冻结用户界面,那么这是一个合理的使用线程。使用BackgroundWorker。MSDN库有很好的帮助