我有一个在两个定时器(Clock和IntervalCounter)上运行的系统。 Clock使用tick事件处理程序来更新每个tick(每秒)的显示,这很简单。 IntervalCounter使用'elapsed'事件处理程序,它输出一个messageBox告诉用户是时候输入下一组数据(每5分钟一次)。
在程序中有一点我希望intervalCounter关闭,因为不再需要警报,但无论我如何尝试实现这一点,警报仍会继续。我试图连接两个定时器,以便在Clock关闭时,IntervalCounter也关闭,但这似乎没有生效。
下面显示了将函数初始化并运行到定时器事件处理程序的代码,以及我希望IntervalCounter关闭的位置处的按钮单击:
'时钟'功能:
private void initialiseClock() //initialisation of Clock Timer
{
Clock = new System.Windows.Forms.Timer();
Clock.Tick += new EventHandler(Clock_Tick); //calls Clock EventHandler
Clock.Interval = 1000; //1 second in miliseconds
Clock.Start();
}
//initialiseClock sub-functions
private void Clock_Tick(object sender, EventArgs e) //Clock EventHandler definition
{
updateTimeDisplay();
checkDisplay();
}
//end initialiseClock sub-functions
'IntervalCounter'功能:
private void initialiseIntervalCounter() //initialisation of IntervalCounter Timer
{
System.Timers.Timer intervalCounter = new System.Timers.Timer();
intervalCounter.Elapsed += new ElapsedEventHandler(intervalAlert); //calls intervalCounter EventHandler
intervalCounter.Interval = 300000; //5 minutes in miliseconds
if (Clock.Enabled == true) //set intervalCounter to rely on Clock
{
intervalCounter.Enabled = true; //turn on when Clock is on
intervalCounter.Start();
}
else if (Clock.Enabled == false)
{
intervalCounter.Enabled = false; //turn off when Clock is off
Clock.Stop();
intervalCounter.Stop();
}
}
//initialiseIntervalCounter sub-functions
private void intervalAlert(object source, ElapsedEventArgs e) //intervalCounter EventHandler definition
{
Clock.Enabled = false;
string alertTitle = "Interval Alert";
string alertMessage = "The 5 minute interval has been reached, enter the current readings";
clearInput();
DialogResult okRes = MessageBox.Show(alertMessage, alertTitle, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
if (okRes == DialogResult.OK)
{
Clock.Enabled = true;
}
}
//end initialiseIntervalCounter sub-functions
btnFinish进程(IntervalCounter应该禁用):
private void btnFinish_Click(object sender, EventArgs e)
{
Clock.Enabled = false; //turn off Clock (and reliant Timers)
string finishmsg = "Save monitoring data and end monitoring"; //message displayed to user
string finishTitle = "End Monitoring Confirmation"; //title of the message box
DialogResult finishRes = MessageBox.Show(finishmsg, finishTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Question); //display messageBox and options
if (finishRes == DialogResult.Yes)
{
saveFileFooter(); //append the footer template and associated variable values to the text file
saveBPChartImage();
MessageBox.Show("The vitals data recorded in this program has been saved to the file: " +
fileName + //file name specified
"\nThe recovery data fields can now be filled in"); //give user file address and direct to completing recovery data
enableRecoveryData();
intervalCounter.Stop();
StopWatch = Stopwatch.StartNew();
}
else
{
Clock.Enabled = true;
intervalCounter.Enabled = true;
}
}
关于从这里去哪里的任何建议都是课堂,谢谢你!
标记
答案 0 :(得分:2)
我发现Timer.Elapsed事件documentation:
即使SynchronizingObject不为null,也可以在调用Dispose或Stop方法之后或者Enabled属性设置为false之后发生Elapsed事件,因为提升Elapsed事件的信号始终排队等待在线程上执行池线程。解决此竞争条件的一种方法是设置一个标志,告诉事件处理程序Elapsed事件忽略后续事件。
也许你应该尝试在你的" intervalAlert"中添加一个标志。事件处理程序像这样:
bool alertIsOFF = false; // Global variable
private void btnFinish_Click(object sender, EventArgs e)
{
Clock.Enabled = false; //turn off Clock (and reliant Timers)
string finishmsg = "Save monitoring data and end monitoring"; //message displayed to user
string finishTitle = "End Monitoring Confirmation"; //title of the message box
DialogResult finishRes = MessageBox.Show(finishmsg, finishTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Question); //display messageBox and options
if (finishRes == DialogResult.Yes)
{
saveFileFooter(); //append the footer template and associated variable values to the text file
saveBPChartImage();
MessageBox.Show("The vitals data recorded in this program has been saved to the file: " +
fileName + //file name specified
"\nThe recovery data fields can now be filled in"); //give user file address and direct to completing recovery data
enableRecoveryData();
intervalCounter.Stop();
alertIsOff = true;
StopWatch = Stopwatch.StartNew();
}
else
{
Clock.Enabled = true;
intervalCounter.Enabled = true;
}
}
//initialiseIntervalCounter sub-functions
private void intervalAlert(object source, ElapsedEventArgs e) //intervalCounter EventHandler definition
{
if (!alertIsOff)
{
Clock.Enabled = false;
string alertTitle = "Interval Alert";
string alertMessage = "The 5 minute interval has been reached, enter the current readings";
clearInput();
DialogResult okRes = MessageBox.Show(alertMessage, alertTitle, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
if (okRes == DialogResult.OK)
{
Clock.Enabled = true;
}
}
}
//end initialiseIntervalCounter sub-functions
答案 1 :(得分:0)
我想你或许只是犯了一个微不足道的编程错误。代码将 - 如图所示 - 不编译,因为intervalConter是initialiseIntervalCounter()中的局部变量。也许您将它单独声明为类变量,这将完美地解释所描述的行为。否则,它应该工作。