Home > Software engineering >  C#: How can I make the clock work correctly?
C#: How can I make the clock work correctly?

Time:01-11

I'm working on a new GitHub repository called Charms Bar Port using Visual Studio 2022 that requires the UI to show a clock and date at the lower left, as seen on this image.

However, the clock seems to never update regardless of the presence of:

  • Background workers
  • Timers

Is there a good way to continuously keep track of the time in a loop?

Using some code for background workers and/or timers from external sources have never functioned. For example: "8:34" will be stuck on the screen even if the time is "9:00".

    Timer t = new Timer();
    private void Form1_Load(object sender, EventArgs e)
    {
        // Normally, the timer is declared at the class level, so that it stays in scope as long as it
        // is needed. If the timer is declared in a long-running method, KeepAlive must be used to prevent
        // the JIT compiler from allowing aggressive garbage collection to occur before the method ends.
        // You can experiment with this by commenting out the class-level declaration and uncommenting
        // the declaration below; then uncomment the GC.KeepAlive(aTimer) at the end of the method.
        //System.Timers.Timer aTimer;

        // Create a timer and set a two second interval.
        t = new System.Timers.Timer();
        t.Interval = 2000;

        // Create a timer with a two second interval.
        //t = new System.Timers.Timer(2000);

        // Hook up the Elapsed event for the timer.
        t.Elapsed  = OnTimedEvent;

        // Have the timer fire repeated events (true is the default)
        t.AutoReset = true;

        // Start the timer
        t.Enabled = true;

        // If the timer is declared in a long-running method, use KeepAlive to prevent garbage collection
        // from occurring before the method ends.
        GC.KeepAlive(t);

    }

    //timer eventhandler
    private void OnTimedEvent(object sender, EventArgs e)
    {
        //update label
            Date.Content = DateTime.Today.ToString("MMMM d");
            Week.Content = DateTime.Today.ToString("dddd");
            Clocks.Content = DateTime.Now.ToString("hh:mm");
        t.Enabled = true;
    }
}

CodePudding user response:

You should use dispatcher to update UI from different thread.

Your code should be:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        _initTimer();
    }
    
    private Timer t = null;
    private readonly Dispatcher dispatcher = Dispatcher.CurrentDispatcher;

    private void _initTimer()
    {
        t = new System.Timers.Timer();
        t.Interval = 1000;
        t.Elapsed  = OnTimedEvent;
        t.AutoReset = true;
        t.Enabled = true;
        t.Start();
    }

    private void OnTimedEvent(object sender, ElapsedEventArgs e)
    {
        dispatcher.BeginInvoke((Action)(() =>
        {
            DateTime today = DateTime.Now;                      
            Clocks.Content = today.ToString("hh:mm:ss");
            // do additional things with captured 'today' variable.
        }));
    }
}
  • Related