tags:

views:

88

answers:

3
+3  Q: 

Clock Application

Hi, I am creating a clock application in C#.Net.I have images for each digits from 0-9. I have a timer in the main page constructor which ticks every seconds

DispatcherTimer tmr = new DispatcherTimer();
tmr.Interval = TimeSpan.FromSeconds(1);
tmr.Tick += new EventHandler(tmr_Tick);
tmr.Start();

void tmr_Tick(object sender, EventArgs e)
    {
        dt = DateTime.Now;
        UpdateSecondsImages(dt);
    }


private void UpdateSecondsImages(DateTime dt)
    {
        secondSource2 = dt.Second % 10;
        secondDigit2.Source = digimgs[secondSource2];
        if (secondSource2 == 0)
        {
            secondSource1 = dt.Second / 10;
            secondDigit1.Source = digimgs[secondSource1];
        }

        if (secondSource1 == 0)
        {
            UpdateMinuteImages(dt);
        }
    }

But the problem I am facing now is this code may skip a second for a minute.Please suggest alternate way to make this smooth from a performance point of view.

+2  A: 

Simple. When you set a timer to go off every second you are saying, "please sleep for at least 1 second before waking up and notifying me". In reality, you could be sleeping for much longer. Also, different timing APIs have clock drift relative to each other. The clock that timers are based on may not be the same clock that the DateTime.Now is based on.

Think of it like this - let's say you are actually be waking up once every 1.02 seconds. Hence, every 50 seconds, you'll skip a beat in rendering. For example you'll go from waking up at "49.98" (rendered as "49") and then your next interval you are woken up at "51.00".

The simple workaround is to sleep for sometime less than 1 second. In your case, I suggest sleeping between 500-750 milliseconds instead of a full second. You can simply re-render the same time again in the case where you wakeup within the same second interval. Or as a trivial optimization, just do nothing when you've already woken up an the second count hasn't changed since previous time.

try saying: tmr.Interval = TimeSpan.FromMilliSeconds(500);

selbie
Hi,It sounds good.I have tried the very same logic,now there is no skip between the seconds but the transition time between two consecutive digits vary at times.Also its eating up my application memmory. Since this is a phone application it feels so costly to give away memmory constraints
Tintu Mon
You should read Raymond Chen's article on why Windows doesn't show a "seconds" count for the tray timer.http://blogs.msdn.com/b/oldnewthing/archive/2003/10/10/55256.aspx
selbie
That's a cool link that you have posted,but I have seen applications showing seconds also :-(
Tintu Mon
Measure the run time of the tick routine and adjust the tick rate to slightly over that. If you do 3/4 second ticks then you'll get a situation where you sometimes get two runs of the routine and sometimes only one. Try tenths of a second instead. It'll hammer the battery life though.The memory usage is all in the image store. You either reduce the data size of the images or load them on demand. Phone flash is slow so on-demand loading might re-introduce the judder.
JonB
How to make my timer synchronize with system timer (DateTime.Now)?
Tintu Mon
@Tintu Mon: Do you think people will notice if your clock is sometimes innaccurate by less than a second? As long as it isn't gaining/losing time I'd say your clock is just fine.
Phil
+1  A: 

If it's okay to show clock only when they're visible, I'd rather suggest to use CompositionTarget.Render event handler. Get current time in it and update the UI appropriately. This will not only eliminate the error but will let you render milliseconds as well :).

I highly doubt this approach impacts performance (cos() and sin() are damn fast in our days). But even if it will (you are rendering thousands of clocks), you can update UI not on every frame.

Hope this helps.

Anvaka
A: 

Yesterday we launched a contest with Ball Watch USA to create watches in Silverlight. I recommend using a Storyboard to rotate the second hand 360 degrees over 1 minute and set the storyboard to repeat forever. Here are some links:

Michael S. Scherotter