2016-04-01 1 views
1

У меня есть несколько проблем с кодом ниже.Таймеры в C# с глобальными переменными?

Когда приложение запускается, как только LookingAwayResult.Text = "Yes", запускается таймер и рассчитывает до 10. Когда LookingAwayResult.Text = "No" или "Maybe", таймер должен остановиться и сбросить обратно в 0 раз, но это не так.

Когда таймер достигает 10, появляется окно с сообщением, которое я хочу, но это продолжит показ и спам моего экрана. Таймер предназначен для возврата обратно в 0 после появления окна сообщения, и приложение замерзает, пока в поле сообщения не будет выбрано «Ok».

Кажется, что мой код зацикливает весь таймер, который не то, что я хочу.

private void OnFaceFrameArrived(object sender, FaceFrameArrivedEventArgs e) 
{ 
    // Retrieve the face reference 
    FaceFrameReference faceRef = e.FrameReference; 

    if (faceRef == null) return; 

    // Acquire the face frame 
    using (FaceFrame faceFrame = faceRef.AcquireFrame()) 
    { 
     if (faceFrame == null) return; 

     // Retrieve the face frame result 
     FaceFrameResult frameResult = faceFrame.FaceFrameResult; 

     // Display the values 
     HappyResult.Text = frameResult.FaceProperties[FaceProperty.Happy].ToString(); 
     EngagedResult.Text = frameResult.FaceProperties[FaceProperty.Engaged].ToString(); 
     GlassesResult.Text = frameResult.FaceProperties[FaceProperty.WearingGlasses].ToString(); 
     LeftEyeResult.Text = frameResult.FaceProperties[FaceProperty.LeftEyeClosed].ToString(); 
     RightEyeResult.Text = frameResult.FaceProperties[FaceProperty.RightEyeClosed].ToString(); 
     MouthOpenResult.Text = frameResult.FaceProperties[FaceProperty.MouthOpen].ToString(); 
     MouthMovedResult.Text = frameResult.FaceProperties[FaceProperty.MouthMoved].ToString(); 


     //initilize look away timer for 10 seconds 
     Timer lookAwayTimer = new Timer(interval: 10000); 

     //inialize the poll tiomer for 50 ms 
     Timer pollTimer = new Timer(interval: 50); 


     LookingAwayResult.Text = frameResult.FaceProperties[FaceProperty.LookingAway].ToString(); 

     //if 10 seconds expires then show message box 
     lookAwayTimer.Elapsed += (s, f) => 
     { 
      MessageBox.Show("Looking is set to yes", "Looking Error", MessageBoxButton.OK); 
     }; 

     //enable poll timer 
     pollTimer.Enabled = true; 

     //check if person is looking. If they are not then enable the lookAwayTimer. If they start looking 
     //then disable the timer 
     pollTimer.Elapsed += (s, f) => 
     { 
      Check = frameResult.FaceProperties[FaceProperty.LookingAway].ToString(); 

      if (Check == "Yes") 
      { 
       lookAwayTimer.Enabled = true; 
      } 
      else 
      { 
       lookAwayTimer.Enabled = false; 
      } 
     }; 
    } 
} 

То, что я после того, как для таймер будет работать после того, как человек не смотрит и останавливается и сбрасывается обратно в 0, когда человек снова смотрит.

Когда таймер достиг 10 секунд, появляется окно сообщения, и приложение замерзает. Пользователь должен выбрать «Ok», чтобы этот флажок исчез, и приложение вернется к значениям по умолчанию.

Из исследования, я полагаю, возможно, использование глобальной переменной или модальной коробки пригодится здесь?

Я считаю, что с помощью модального блока это заморозит мое приложение, пока пользователь ничего не сделает с ним? Но это все еще не решает моих проблем с таймером, не возвращаясь обратно к 0 и желая, чтобы приложение полностью сбросилось после выбора «ОК».

Я также подчеркиваю, что глобальные переменные в C# следует избегать, если это необходимо.

Если модальная коробка является ответом для части этого, я бы просто изменил MessageBox.Show на ShowDialog?

ответ

0

С вашего вопроса ясно, что вы не контролируете какую-либо операцию при нажатии кнопок окна сообщений. Вы можете отображать окно сообщения только для уведомления пользователю.

Так, чтобы ваш код не приостанавливался во время выполнения создания окна сообщения на different thread, поэтому выполнение не будет остановлено.

Следующий код создает поле Message в отдельной теме.

public class ThreadIndependentMB 
    { 
     private readonly Dispatcher uiDisp; 
     private readonly Window ownerWindow; 

     public ThreadIndependentMB(Dispatcher UIDispatcher, Window owner) 
     { 
      uiDisp = UIDispatcher; 
      ownerWindow = owner; 
     } 

     public MessageBoxResult Show(string msg, string caption="", 
      MessageBoxButton buttons=MessageBoxButton.OK, 
      MessageBoxImage image=MessageBoxImage.Information) 
     { 
      MessageBoxResult resmb = new MessageBoxResult(); 
      if (ownerWindow != null) 
      uiDisp.Invoke(new Action(() => 
      { 
       resmb = MessageBox.Show(ownerWindow, msg, caption, buttons, image); 

      })); 
      else 
       uiDisp.Invoke(new Action(() => 
       { 
        resmb = MessageBox.Show(msg, caption, buttons, image); 

       })); 
      return resmb; 
     } 


    } 

Noe в вашем таймере вы можете создать экземпляр класса и вызвать метод Show этого класса.

+0

Как я могу реализовать этот код, чтобы делать то, что мне нужно, с таймерами? Что мне нужно изменить? – lfctez

+0

Просто создайте объект вышеуказанного класса и вызовите метод show класса в прошедшем событии вместо MessageBox.Show() –

0

AutoReset свойство на таймере может решить вашу проблему:

System.Timers.Timer lookAwayTimer = new System.Timers.Timer(10000) 
{ 
    AutoReset = false 
}; 

lookAwayTimer.Elapsed += (object sender, System.Timers.ElapsedEventArgs e) => 
    { 
     pollTimer.Stop(); 
     MessageBox.Show("Looking is set to yes", "Looking Error", MessageBoxButtons.OK); 
     lookAwayTimer.Start(); 
     pollTimer.Start(); 
    }; 

Установка этого ложного вызовет таймер истечь один раз, а затем остановить повторение (так оно не спам ваш экран), пока вы не запустите его снова - значение по умолчанию истинно, поэтому он будет сохранять автоматический сброс и вызывать этот метод каждые 10 секунд.

+0

Я пробовал это, и окно сообщения продолжает появляться :( – lfctez

+0

@lfctez Возможно, вам также следует остановить таймер опроса? Поскольку он все еще работает и снова включит lookAwayTimer, даже если сообщение появилось? Я обновил свой ответ так, как вы могли бы это сделать. – TVOHM

+0

Пробовал это, и это все равно то же самое жаль :( – lfctez