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.
}));
}
}