Setting up a second thread doesn't actually help in any way that I can
see...  It also makes life a lot more complex in a Windows Forms app because
you aren't actually allowed to do anything to the UI from a worker thread.

But if you want to reduce the number of events to exactly one per second,
yet still be aligned as closely as possible to the second boundary, try
this:

    private void timer_Tick(object sender, System.EventArgs e)
    {
        int ms = DateTime.Now.Millisecond;
        timer.Interval = 1000 - ms;

        Debug.WriteLine(ms.ToString());

        // Do whatever you want to do every second...
        label1.Text = DateTime.Now.ToString();
    }

When I run this, the Debug.WriteLine output indicates that once the program
is up and running the event always fires within 10ms of the second boundary,
which seems pretty good to me.  Certainly close enough to it that there will
be no perceptible delay for UI work.  And also a good deal closer than
you'll get with 10 calls a second (which is slow enough for any clock creep
to cause perceptible 'steps' in the regularity of your clock ticks).

If changing the interval every time offends your sensibilities (this
actually disables and re-enables the timer every time, so has its costs -
this actually ends up calling KillTimer each time and then creating a new
timer...), then you could do this:

    int ms = DateTime.Now.Millisecond;
    if (ms > 30)
        timer.Interval = 1000 - ms;
    else
        timer.Interval = 1000;

This may look no better for performance, but if you set the Interval
property to the value that it already has, it has no effect. (I.e. it only
actually disables and reenables the timer when you really change the
interval.)  This means that the timer will only be changed when it has
creeped by more than 30ms.  (30ms is about the point at which discrepancies
become visible.)

Interestingly I find that on my system it creeps forwards by 1ms every
second!  That's more than I would have expected.  (So I end up adjusting the
timer every 30 seconds or so just to keep aligned.)  I'm not sure why this
is, as I would have expected the Windows Forms timer to derive ultimately
from the same time base as DateTime.


--
Ian Griffiths
DevelopMentor

----- Original Message -----
From: "Peter Foreman" <[EMAIL PROTECTED]>


> --- David Brown <[EMAIL PROTECTED]> wrote:
> > Designing a little clock .Net beastie. I'm unable to determine how, if
even
> > possible, to have .Net tell me when the system clock updates
(specifically, the
> > second). Currently I have a simple WinForm Timer object at 100ms and
checking
> > the DateTime.Now for a changed value. Inefficient, but it works.
>
> Entirely suitable technique IMO.  It is what Petzold uses in his Windows
Forms book.  And ten
> messages a second is not a huge amount by any means.
>
> > Anyone know of a better way?
>
> Not that is as good.  You could set up a separate thread, but I'd say that
is probably a worse
> technique overall.

You can read messages from the DOTNET archive, unsubscribe from DOTNET, or
subscribe to other DevelopMentor lists at http://discuss.develop.com.

Reply via email to