C# - System.Timers.Timer不会关闭

时间:2015-06-26 19:07:36

标签: c# timer

我有一个在两个定时器(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;
        }
    }

关于从这里去哪里的任何建议都是课堂,谢谢你!

标记

2 个答案:

答案 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()中的局部变量。也许您将它单独声明为类变量,这将完美地解释所描述的行为。否则,它应该工作。