[英]I have a C# Windows Forms Application and I want the user to be able to schedule a recurring task
My application sends out an email based on data from the entered form on the UI. 我的应用程序根据UI上输入的表单中的数据发送电子邮件。 The UI also allows them to "schedule" this as a job. 用户界面还允许他们“安排”这项工作。 I don't really want to use outside classes, eg Quartz. 我真的不想使用外部类,例如Quartz。 I also don't want to use the task scheduler as this would require completely rewriting my app... I understand that this can be done with timers, and I have attempted to use the Windows.Forms.Timer, however, I am not getting the desired results. 我也不想使用任务计划程序,因为这将需要完全重写我的应用程序……我知道这可以通过计时器来完成,并且我尝试使用Windows.Forms.Timer,但是,我不是获得预期的结果。 I want it to run at the user specified interval and time, until the set end date. 我希望它以用户指定的时间间隔和时间运行,直到设置的结束日期。
private void Submit_Btn_Click(object sender, EventArgs e)
{
bool run = false;
Location_Alert_Timer.Tick += new EventHandler(Location_Alert_Timer_Tick);
if (Schedule_Chk.Checked == true)
{
run = true;
if (Recur_Txt.Text != "" || Recur_Txt.Text != "0")
{
while (run == true)
{
if ((Convert.ToDateTime(DateTime.Now.ToString("MM/dd/yyyy HH:mm")) <= Convert.ToDateTime(End_Date.Value.ToString("MM/dd/yyyy") + " " + Recur_Time_Txt.Text)))
{
//Execute_Command();
DateTime dt1;
DateTime dt2;
TimeSpan ts = new TimeSpan(Convert.ToInt16(Recur_Txt.Text),0,0,0);
//TimeSpan ts = new TimeSpan(0,0,30);
dt1 = Convert.ToDateTime(DateTime.Now.ToString("MM/dd/yyyy HH:mm"));
dt2 = Convert.ToDateTime(DateTime.Now.ToString("MM/dd/yyyy") + " " + Recur_Time_Txt.Text);
if (dt1 >= dt2)
{
Execute_Command();
Location_Alert_Timer.Interval = (Convert.ToDateTime(DateTime.Now.ToString("MM/dd/yyyy") + " " + Recur_Time_Txt.Text + ":00.000").Add(ts) - DateTime.Now).Milliseconds;
Location_Alert_Timer.Start();
while (Convert.ToDateTime(DateTime.Now.ToString("MM/dd/yyyy HH:mm")) <= Convert.ToDateTime(End_Date.Value.ToString("MM/dd/yyyy") + " " + Recur_Time_Txt.Text))
{
Application.DoEvents();
}
}
else
{
Location_Alert_Timer.Interval = (Convert.ToDateTime(DateTime.Now.ToString("MM/dd/yyyy") + " " + Recur_Time_Txt.Text + ":00.000") - DateTime.Now).Milliseconds;
Location_Alert_Timer.Start();
while (exitFlag == false)
{
Application.DoEvents();
}
}
}
else
{
Location_Alert_Timer.Stop();
run = false;
}
}
}
else
{
Execute_Command();
}
}
else
{
Execute_Command();
}
}
void Location_Alert_Timer_Tick(object sender, EventArgs e)
{
if (Convert.ToDateTime(DateTime.Now.ToString("MM/dd/yyyy HH:mm")) <= Convert.ToDateTime(End_Date.Value.ToString("MM/dd/yyyy") + " " + Recur_Time_Txt.Text))
{
Execute_Command();
}
else
{
exitFlag = true;
}
}
My timer events do not seem to be firing right and I know it is because I have set them up incorrectly... 我的计时器事件似乎触发不正确,我知道这是因为我没有正确设置它们...
Here is the form UI: 这是表单UI:
If anyone has a similar implementation in the future, @itsmatt's explanation led me to rewrite my whole event, from the ground up...below is the final implementation, and it works fantastically: 如果将来有人实现类似的实现,则@itsmatt的解释会导致我从头开始重写整个事件...下面是最终的实现,并且效果非常好:
private void Submit_Btn_Click(object sender, EventArgs e)
{
bool run = false;
if (Schedule_Chk.Checked == true)
{
run = true;
if (Recur_Txt.Text != "" || Recur_Txt.Text != "0")
{
while (run == true)
{
if ((Convert.ToDateTime(DateTime.Now.ToString("MM/dd/yyyy HH:mm")) <= Convert.ToDateTime(End_Date.Value.ToString("MM/dd/yyyy") + " " + Recur_Time_Txt.Text)))
{
DateTime dt1;
DateTime dt2;
TimeSpan ts = new TimeSpan(Convert.ToInt16(Recur_Txt.Text),0,0,0);
dt1 = Convert.ToDateTime(DateTime.Now.ToString("MM/dd/yyyy HH:mm"));
dt2 = Convert.ToDateTime(DateTime.Now.ToString("MM/dd/yyyy") + " " + Recur_Time_Txt.Text);
if (dt1 >= dt2)
{
Execute_Command();
Location_Alert_Timer.Interval = Convert.ToInt32((Convert.ToDateTime(DateTime.Now.ToString("MM/dd/yyyy") + " " + Recur_Time_Txt.Text + ":00.000").Add(ts) - DateTime.Now).TotalMilliseconds);
Location_Alert_Timer.Start();
timerActive = true;
TimerHold();
}
else
{
Location_Alert_Timer.Interval = Convert.ToInt32((Convert.ToDateTime(DateTime.Now.ToString("MM/dd/yyyy") + " " + Recur_Time_Txt.Text + ":00.000") - DateTime.Now).TotalMilliseconds);
singleuse = true;
Location_Alert_Timer.Start();
timerActive = true;
TimerHold();
MessageBox.Show(DateTime.Now.ToString());
MessageBox.Show(DateTime.Now.Add(ts).ToString());
MessageBox.Show((Convert.ToDateTime(DateTime.Now.Add(ts).ToString()) - DateTime.Now).TotalMilliseconds.ToString());
Location_Alert_Timer.Interval = Convert.ToInt32((Convert.ToDateTime(DateTime.Now.Add(ts).ToString()) - DateTime.Now).TotalMilliseconds);
Location_Alert_Timer.Start();
timerActive = true;
TimerHold();
}
}
else
{
Location_Alert_Timer.Stop();
run = false;
}
}
}
}
}
public void TimerHold()
{
while (timerActive)
{
Application.DoEvents();
}
}
void Location_Alert_Timer_Tick(object sender, EventArgs e)
{
if (singleuse)
{
if (uses < 1)
{
if (Convert.ToDateTime(DateTime.Now.ToString("MM/dd/yyyy HH:mm")) <= Convert.ToDateTime(End_Date.Value.ToString("MM/dd/yyyy") + " " + Recur_Time_Txt.Text))
{
uses++;
//DoItOnce();
Execute_Command();
}
else
{
timerActive = false;
}
}
else
{
singleuse = false;
timerActive = false;
Location_Alert_Timer.Stop();
}
}
else
{
if (Convert.ToDateTime(DateTime.Now.ToString("MM/dd/yyyy HH:mm")) <= Convert.ToDateTime(End_Date.Value.ToString("MM/dd/yyyy") + " " + Recur_Time_Txt.Text))
{
//DoIt();
Execute_Command();
}
else
{
timerActive = false;
}
}
}
what about using something like this example? 使用类似这个例子的东西怎么办?
@kclewis Registering the tick event handler in the submit button click handler like you have will result in Location_Alert_Timer_Tick() being called once the first time the button is clicked, twice the next time, etc. It is registering the same callback function over and over, which results in multiple calls to that when the tick event is raised. @kclewis像您一样在提交按钮单击处理程序中注册滴答事件处理程序,将导致第一次单击该按钮一次,再次单击两次则调用Location_Alert_Timer_Tick(),等等。它一遍又一遍地注册相同的回调函数,当出现tick事件时,会导致对该调用的多次调用。 Instead, += that event handler at init time (could be in the constructor or some other setup() function). 而是在初始化时+ =该事件处理程序(可以在构造函数中或其他一些setup()函数中)。 That way you get one and only one function call to Location_Alert_Timer_Tick() when the timer tick event is raised. 这样,当计时器滴答事件触发时,您将只有一个函数调用Location_Alert_Timer_Tick()。 Posted via community wiki for @itsmatt 通过社区Wiki发布@itsmatt
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.