线程池中定时器的使用
我正在为我的公司开发一个在服务器上运行的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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
在您的情况下,由于它是一个 Windows 窗体应用程序,并且您可能希望更新计时器事件处理程序中的 UI,因此我建议使用
Windows.Forms.Timer
。使用 Windows.Forms.Timer 非常简单。在表单的设计视图中,从工具箱中选择
Timer
并将其放在表单上。然后,单击它来设置属性。您希望将Interval
设置为3000
(即 3000 毫秒),并将Enabled
设置为False
。在“事件”选项卡上,双击“Tick”事件,IDE 将为您创建一个处理程序。您希望事件处理程序看起来像这样:
您需要启动计时器(将
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 theTimer
from the Toolbox and drop it on your form. Then, click on it to set the properties. You want to setInterval
to3000
(that's 3000 milliseconds), andEnabled
toFalse
.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:
You'll need to start the timer (set
Enabled
toTrue
). You can do that in yourCreate
event handler, or you can enable it when the user hits the Start button. You can also stop it at any time by settingEnabled
toFalse
.System.Thread.Timer
和Windows.Forms.Timer
的行为不同。System.Thread.Timer
将在系统线程上运行。它有一个内部线程池,因此它不会在您显式创建的线程之一上运行。每个时间间隔,计时器池中的线程之一都会运行您初始化对象的回调。Windows.Forms.Timer
将在当前线程上引发Tick
事件,并且每个时间间隔都会执行此操作,直到您将其禁用。我无法告诉您哪个更适合您的情况;这取决于您是否要在 UI 线程上运行计时器以及其他因素。
System.Thread.Timer
andWindows.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 theTick
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.
试试这个:
Try this: