线程池中定时器的使用

发布于 2024-10-20 05:22:50 字数 2730 浏览 2 评论 0原文

我正在为我的公司开发一个在服务器上运行的Windows应用程序。它是一个多线程应用程序,我为此使用线程池。

我的应用程序电子邮件模块由 3 个主要方法组成。第一种方法从数据库获取新的活动,第二种方法决定活动将通过电子邮件发送给谁,第三种方法发送它。

当我启动应用程序时,第一个方法进入线程池,如果有新的活动,则使用活动信息调用第二个方法。但是,当这些都发生时,第一种方法必须每三秒检查一次数据库是否有新的活动。

我不确定是否必须使用 System.Windows.Forms.Timer 类或 System.Threading.Timer?

而且我不知道如何实施?我是否要使用 Invoke Function 来调用主 UI 之外的线程?您能否发布示例代码并建议最佳实践? 非常感谢

这是我的代码:

private void btnStart_MouseClick(object sender, MouseEventArgs e)
    {
        smartThreadPool = new SmartThreadPool();
        workItemGroup = smartThreadPool.CreateWorkItemsGroup(1);
        workItemGroup.QueueWorkItem(CheckNewCampaigns);
        //smartThreadPool.QueueWorkItem(new WorkItemCallback(this.CheckNewCampaigns));            
    }

    private object CheckNewCampaigns(object state) // 1st method
    {
        StringBuilder builder = new StringBuilder();
        IEnumerable<Campaigns> CampaignsList = DatabaseManager.GetCampaignsList(DatabaseManager.GetNewCampaigns());

        foreach (Campaigns Campaign in CampaignsList)
        {
            builder.AppendFormat("New Campaign Arrived($) --> {0}\r\n", DateTime.Now.ToLongTimeString());
            builder.AppendFormat("CampaignID              --> {0}\r\n", Campaign.CampaignID);
            builder.AppendFormat("CustomerID              --> {0}\r\n", Campaign.CustomerID);
            builder.AppendFormat("ClientID                --> {0}\r\n", Campaign.ClientID);
            builder.AppendFormat("Title                   --> {0}\r\n", Campaign.Title);
            builder.AppendFormat("Subject                 --> {0}\r\n", Campaign.Subject);
            builder.AppendFormat("Status              --> {0}\r\n", Campaign.Status);
        }

        Console.WriteLine(builder.ToString());

        workItemGroup.QueueWorkItem(new WorkItemCallback(this.PrepareCampaignEmail), 2);
        return true;
    }

    private object PrepareCampaignEmail(object CampaignID)  // Second Method
    {
        int campaignID = (int)CampaignID;
        IEnumerable<Campaigns> CampaignDetailsList = DatabaseManager.GetCampaignsList(DatabaseManager.GetCampaignDetails(campaignID)); // bir tane campaign gelmekte
        IEnumerable<Subscribers> SubscribersList = DatabaseManager.GetCampaignSubscribersList(DatabaseManager.GetCampaignSubscribers(campaignID));
        ArrayList test = new ArrayList();

        DataTable dtCustomValuesForCampaign = DatabaseManager.GetCustomValuesForCampaign(campaignID);

        foreach (Subscribers subscriber in SubscribersList)
        {
            workItemGroup.QueueWorkItem(new WorkItemCallback(this.SendEmail), subscriber.Email);
        }

        return true;
    }

I am developing a windows application for my company that runs on the server. It is a multi threaded application, and i am using Thread Pool for that.

My Application Email module consists of 3 major methods. 1st method gets new campaigns from database, second method decides to whom the campaign is going to be sent via email and third method sends it.

When I start the application, 1st method goes into Thread Pool, if there is a new campaign, 2nd method is invoked with the campaign info. But while these all are happening, first method has to check database in every three seconds if there is a new campaign or not.

I am not sure if I have to use System.Windows.Forms.Timer class for that or System.Threading.Timer??

And I am not sure how to implement it? Am I going to use Invoke Function to invoke thread outside the main UI? Could you please post an example code and suggest best practices??
Thanks a lot

Here is my code :

private void btnStart_MouseClick(object sender, MouseEventArgs e)
    {
        smartThreadPool = new SmartThreadPool();
        workItemGroup = smartThreadPool.CreateWorkItemsGroup(1);
        workItemGroup.QueueWorkItem(CheckNewCampaigns);
        //smartThreadPool.QueueWorkItem(new WorkItemCallback(this.CheckNewCampaigns));            
    }

    private object CheckNewCampaigns(object state) // 1st method
    {
        StringBuilder builder = new StringBuilder();
        IEnumerable<Campaigns> CampaignsList = DatabaseManager.GetCampaignsList(DatabaseManager.GetNewCampaigns());

        foreach (Campaigns Campaign in CampaignsList)
        {
            builder.AppendFormat("New Campaign Arrived($) --> {0}\r\n", DateTime.Now.ToLongTimeString());
            builder.AppendFormat("CampaignID              --> {0}\r\n", Campaign.CampaignID);
            builder.AppendFormat("CustomerID              --> {0}\r\n", Campaign.CustomerID);
            builder.AppendFormat("ClientID                --> {0}\r\n", Campaign.ClientID);
            builder.AppendFormat("Title                   --> {0}\r\n", Campaign.Title);
            builder.AppendFormat("Subject                 --> {0}\r\n", Campaign.Subject);
            builder.AppendFormat("Status              --> {0}\r\n", Campaign.Status);
        }

        Console.WriteLine(builder.ToString());

        workItemGroup.QueueWorkItem(new WorkItemCallback(this.PrepareCampaignEmail), 2);
        return true;
    }

    private object PrepareCampaignEmail(object CampaignID)  // Second Method
    {
        int campaignID = (int)CampaignID;
        IEnumerable<Campaigns> CampaignDetailsList = DatabaseManager.GetCampaignsList(DatabaseManager.GetCampaignDetails(campaignID)); // bir tane campaign gelmekte
        IEnumerable<Subscribers> SubscribersList = DatabaseManager.GetCampaignSubscribersList(DatabaseManager.GetCampaignSubscribers(campaignID));
        ArrayList test = new ArrayList();

        DataTable dtCustomValuesForCampaign = DatabaseManager.GetCustomValuesForCampaign(campaignID);

        foreach (Subscribers subscriber in SubscribersList)
        {
            workItemGroup.QueueWorkItem(new WorkItemCallback(this.SendEmail), subscriber.Email);
        }

        return true;
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

南街九尾狐 2024-10-27 05:22:50

在您的情况下,由于它是一个 Windows 窗体应用程序,并且您可能希望更新计时器事件处理程序中的 UI,因此我建议使用 Windows.Forms.Timer

使用 Windows.Forms.Timer 非常简单。在表单的设计视图中,从工具箱中选择Timer并将其放在表单上。然后,单击它来设置属性。您希望将 Interval 设置为 3000(即 3000 毫秒),并将 Enabled 设置为 False

在“事件”选项卡上,双击“Tick”事件,IDE 将为您创建一个处理程序。您希望事件处理程序看起来像这样:

private void timer1_Tick(object sender, EventArgs e)
{
    var stateObj = // create your state object here
    CheckNewCampaigns(stateObj);
}

您需要启动计时器(将 Enabled 设置为 True)。您可以在 Create 事件处理程序中执行此操作,也可以在用户单击“开始”按钮时启用它。您还可以随时将 Enabled 设置为 False 来停止它。

In your situation, since it's a Windows Forms application and you'll potentially want to update the UI in the timer event handler, I'd suggest using Windows.Forms.Timer.

Using Windows.Forms.Timer is pretty easy. In the design view of your form, select the Timer from the Toolbox and drop it on your form. Then, click on it to set the properties. You want to set Interval to 3000 (that's 3000 milliseconds), and Enabled to False.

On the Events tab, double-click the Tick event and the IDE will create a handler for you. You want the event handler to look something like this:

private void timer1_Tick(object sender, EventArgs e)
{
    var stateObj = // create your state object here
    CheckNewCampaigns(stateObj);
}

You'll need to start the timer (set Enabled to True). You can do that in your Create event handler, or you can enable it when the user hits the Start button. You can also stop it at any time by setting Enabled to False.

叶落知秋 2024-10-27 05:22:50

System.Thread.TimerWindows.Forms.Timer 的行为不同。

System.Thread.Timer 将在系统线程上运行。它有一个内部线程池,因此它不会在您显式创建的线程之一上运行。每个时间间隔,计时器池中的线程之一都会运行您初始化对象的回调。

Windows.Forms.Timer 将在当前线程上引发Tick 事件,并且每个时间间隔都会执行此操作,直到您将其禁用。

我无法告诉您哪个更适合您的情况;这取决于您是否要在 UI 线程上运行计时器以及其他因素。

System.Thread.Timer and Windows.Forms.Timer act differently.

The System.Thread.Timer will run on a system thread. It has an internal thread pool, so it won't be run on one of the threads you explicitly created. Every interval, one of the threads in the Timer's pool will run the callback you initialized the object with.

The Windows.Forms.Timer will raise the Tick event on the current thread and will do so every interval, until you disable it.

I can't tell you which is more appropriate for your situation; it depends on whether you want to run the timer on the UI thread, as well as other factors.

り繁华旳梦境 2024-10-27 05:22:50

试试这个:

public void EnableTimer()
        {
            if (this.InvokeRequired)
                this.Invoke(new Action(EnableTimer));
            else
                this.timer1.Enabled = true;
        }

Try this:

public void EnableTimer()
        {
            if (this.InvokeRequired)
                this.Invoke(new Action(EnableTimer));
            else
                this.timer1.Enabled = true;
        }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文