我正在为我的公司开发一个在服务器上运行的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;
}
答案 0 :(得分:1)
System.Thread.Timer
和Windows.Forms.Timer
采取不同的行动。
System.Thread.Timer
将在系统主题上运行。它有一个内部线程池,因此它不会在您明确创建的其中一个线程上运行。每个时间间隔,Timer池中的一个线程将运行您使用初始化对象的回调。
Windows.Forms.Timer
会在当前主题上引发Tick
事件,并且会在每个时间间隔内执行此操作,直到您将其禁用为止。
我无法告诉你哪种情况更适合你的情况;这取决于你是否想在UI线程上运行计时器,以及其他因素。
答案 1 :(得分:1)
在您的情况下,由于它是Windows窗体应用程序,并且您可能希望更新计时器事件处理程序中的UI,我建议使用Windows.Forms.Timer
。
使用Windows.Forms.Timer
非常简单。在表单的设计视图中,从工具箱中选择Timer
并将其放在表单上。然后,单击它以设置属性。您希望将Interval
设置为3000
(即3000毫秒),将Enabled
设置为False
。
在Events选项卡上,双击Tick事件,IDE将为您创建一个处理程序。您希望事件处理程序看起来像这样:
private void timer1_Tick(object sender, EventArgs e)
{
var stateObj = // create your state object here
CheckNewCampaigns(stateObj);
}
您需要启动计时器(将Enabled
设置为True
)。您可以在Create
事件处理程序中执行此操作,也可以在用户点击“开始”按钮时启用它。您也可以随时将Enabled
设置为False
来停止播放。
答案 2 :(得分:0)
试试这个:
public void EnableTimer()
{
if (this.InvokeRequired)
this.Invoke(new Action(EnableTimer));
else
this.timer1.Enabled = true;
}