0

I have a countdown which uses the method recommended in the second answer to this question (substracting the start time from the current time).

The trouble is, when I pause it and then resume it a few seconds later, although the display freezes, the countdown has in the interval continued. I know this is because the start time and the current time haven't changed (!) but I can't think how logically to remedy it.

Selected Code:

private DispatcherTimer cdTimer;
private DateTime startTime;
private TimeSpan countdownFrom = new TimeSpan(0, 30, 0);

cdTimer= new DispatcherTimer();
cdTimer.Interval = new TimeSpan(0, 0, 0, 0, 1);
showTime.Text = countdownFrom .Minutes.ToString("D2") + ':' + countdownFrom .Seconds.ToString("D2");

void cdTimer_Tick(object sender, EventArgs e)
{
  TimeSpan difference = DateTime.Now - startTime;
  TimeSpan countdown = countdownFrom - difference;
  showTime.Text = countdown.Minutes.ToString("D2") + ':' + countdown.Seconds.ToString("D2");
  if (countdown.Hours == 0 && countdown.Minutes == 0 && countdown.Seconds == 0 &&   countdown.Milliseconds <= 100)
  {
    cdTimer.Stop();
    cdTimer.Tick -= new EventHandler(cdTimer_Tick);
  }
}

private void start_Click(object sender, RoutedEventArgs e)
{
  startTime = DateTime.Now;
  cdTimer.Tick += new EventHandler(cdTimer_Tick);
  cdTimer.Start();
}

private void pause_Click(object sender, RoutedEventArgs e)
{
  if (!paused) {
    cdTimer.Stop();
    paused = true;
  } else {
    cdTimer.Start();
    paused = false;
  }
}
Community
  • 1
  • 1
GluePear
  • 7,244
  • 20
  • 67
  • 120
  • 1
    How do you unpause, that's missing from the code? Just starting the cdTimer again? If you don't change the startTime variable, of course the elapsed time from the start will be bigger each second, paused or not paused. – Sami Kuhmonen May 20 '14 at 20:55
  • Ha, poorly worded question, sorry - I missed the most important bit. Yes, I simply start it again, and I know that that's the problem, my brain is just refusing to calculate how the `startTime` variable will be recalculated... – GluePear May 20 '14 at 20:58

1 Answers1

1

On every pause, squirrel away the running time to-date. Then add that on the calculation:

    private TimeSpan _runningTime = new TimeSpan();
    private void pause_Click()
    {
     if (!paused) {
       _runningTime = _runningTime.Add(DateTime.Now - startTime);
       cdTimer.Stop();
       paused = true;
     } else {
       startTime = DateTime.Now;
       cdTimer.Start();
       paused = false;
     }
    }

    void cdTime_Tick()
    {
        // ...
        TimeSpan difference = DateTime.Now - startTime;
        difference = difference.Add(_runningTime);
        TimeSpan countdown = countdownFrom - difference;
        // ...
    }

EDIT: Updated running time logic

John Arlen
  • 6,539
  • 2
  • 33
  • 42
  • Thanks John, but it's acting a bit erratically, sometimes (upon resumption) actually adding on more time than I started with... – GluePear May 20 '14 at 21:08
  • @GluePear: Updated - was adding to the wrong entry. Test Fail. – John Arlen May 20 '14 at 21:16
  • Thanks again -- it's still not working as expected: this time, each resumption takes a largish chunk out of the remaining time. Should I be doing something on the unpause code perhaps? – GluePear May 20 '14 at 21:23
  • In your edited code, the restart part of Pause() needs to reset startTime. I think if you stop and think about what it is doing, you can apply the details to your code. – John Arlen May 20 '14 at 21:28