2015-06-26 4 views
0

У меня есть система, которая работает на двух таймерах (Clock and IntervalCounter). Clock использует обработчик события tick для обновления дисплея на каждом тике (каждую секунду), что достаточно просто. IntervalCounter использует обработчик событий «прошедший», который выводит messageBox, чтобы сообщить пользователю, что пришло время ввести следующий набор данных (каждые 5 минут).C# - System.Timers.Timer не отключается

Во время программы есть точка, в которой я хочу, чтобы 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

См. Http://stackoverflow.com/questions/18280330/system-timers-timer-elapsed-event-executing-after-timer-stop-is-called –

+0

Вы делаете несколько ошибок, вы никогда не получите это код идет. Вы еще не готовы к System.Timers.Timer. Фрэнки, мало программистов, это очень неприятный класс. В этом коде просто нет никакой пользы, просто используйте обычный System.Windows.Forms.Timer(). –

ответ

2

я обнаружил, что на Timer.Elapsed Event documentation:

Даже если SynchronizingObject не равно нуля, истекшее событие может произойти после того, как метод Dispose или остановки был вызван или после Enabled свойство было установлено в false, потому что сигнал поднять событие 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 
+0

Это сработало отлично, спасибо, сэр! – marcuthh

0

Я думаю, вы, возможно, просто сделали тривиальную ошибку программирования. Код будет - как показано - не компилироваться, потому что ваш интервал -контер является локальной переменной в initialiseIntervalCounter(). Возможно, вы объявили его отдельно как переменную класса, что прекрасно объяснит описанное поведение. В противном случае он должен работать.

Смежные вопросы