I made a simple WPF
full screen and always on top window, which has a clock with dddd dd MMMM yyyy
HH:mm:ss
timestamp. The application is open 24/24 on a always on touch-screen, the problem is that after some time I see the clock freezed at a certain time. The application isn't freezed by itself, because I put some buttons and it is totally working.
How I update the clock TextBox
In all versions of the clock I have this same problem!
1. Task version
private Task _clock;
private void LoadClock()
{
_clockCancellationTokenSource = new CancellationTokenSource();
_clock = Task.Run(async () =>
{
try
{
while (!_clockCancellationTokenSource.IsCancellationRequested)
{
DateTime now = DateTime.Now;
_ = Dispatcher.InvokeAsync(() =>
{
txtHour.Text = DateTime.Now.ToString("HH:mm:ss", CultureInfo.CurrentCulture);
txtDate.Text = now.ToString("dddd dd MMMM yyyy", CultureInfo.CurrentCulture);
},
DispatcherPriority.Normal);
await Task.Delay(800, _clockCancellationTokenSource.Token);
}
}
catch
{
// I don't do anything with the errors here, If any
}
}, _clockCancellationTokenSource.Token);
}
And in Page_Unloaded
event:
if (_clock != null && !_clock.IsCompleted)
{
_clockCancellationTokenSource?.Cancel();
_clock.Wait();
_clock.Dispose();
_clockCancellationTokenSource?.Dispose();
}
2. DispatcherTimer version
private DispatcherTimer _clock;
private void LoadClock(bool show)
{
_clock = new DispatcherTimer
{
Interval = TimeSpan.FromSeconds(1)
};
_clockTimer_Tick(null, null);
_clock.Tick += _clockTimer_Tick;
_clock.Start();
}
private void _clockTimer_Tick(object sender, object e)
{
var now = DateTime.Now;
txtHour.Text = DateTime.Now.ToString("HH:mm:ss", CultureInfo.CurrentCulture);
txtDate.Text = now.ToString("dddd dd MMMM yyyy", CultureInfo.CurrentCulture);
}
And in Page_Unloaded
event:
if (_clock != null)
{
_clock.Stop();
_clock.Tick -= _clockTimer_Tick;
}
3. System.Timers.Timer version
private Timer _clock;
private void LoadClock(bool show)
{
// Timer per gestire l'orario
_clock = new Timer(800);
_clock.Elapsed += _clock_Elapsed;
_clock.Start();
_clock_Elapsed(null, null);
}
private void _clock_Elapsed(object sender, ElapsedEventArgs e)
{
DateTime now = DateTime.Now;
Dispatcher.Invoke(() =>
{
txtHour.Text = DateTime.Now.ToString("HH:mm:ss", CultureInfo.CurrentCulture);
txtDate.Text = now.ToString("dddd dd MMMM yyyy", CultureInfo.CurrentCulture);
});
}
And in Page_Unloaded
event:
_clock.Stop();
_clock.Elapsed -= _clock_Elapsed;
_clock.Dispose();
What I have tried so far:
- Changing the timers implementation as you seen from my code
- Adding a log in the timer
tick
callback to see if It stops due to a UI dispatch problem or a timer problem. It's interesting that I see that the timer after a certain amount of time stops ticking. - I thought It could be something with Windows, that maybe stops the additional threads, but I didn't find any clue about this!
Do you have any suggestions?