I am trying to simulate the behavior of a clock. For that, I create an Observable.Interval
that, after a specified time interval, updates the value of a property by the equivalent amount of time. The value is data-bound to the GUI.
The problem is: the "clock" runs quite slower than expected, that is, it takes longer than one second for the clock value to increase one second.
The finer the desired time resolution (the value of MILLIS_INTERVAL
below), the worse the problem gets (I tested it with values of 1, 10, 100 and other submultiples of 1000, since TimeSpan.FromMilliseconds
is documented to have a maximum resolution of 1ms).
I would expect the observable callback to run asynchronously, and be fired at regular intervals, possibly in parallel, despite the time it takes to execute, but it seems that the larger the frequency, the more it lags.
ViewModel
using System; using System.ComponentModel; using System.Reactive.Linq; namespace IntervalClock { public class ViewModel : INotifyPropertyChanged { public double TimeSeconds { get { return _timeSeconds; } set { _timeSeconds = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("TimeSeconds")); } } double _timeSeconds; const double MILLIS_INTERVAL = 10; public ViewModel() { Observable.Interval(TimeSpan.FromMilliseconds(MILLIS_INTERVAL)) .Subscribe(token => TimeSeconds += MILLIS_INTERVAL / 1000); } public event PropertyChangedEventHandler PropertyChanged; } }
MainWindow:
<Window x:Class="IntervalClock.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:IntervalClock"
mc:Ignorable="d">
<Window.DataContext>
<local:ViewModel/>
</Window.DataContext>
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock Text="{Binding TimeSeconds, StringFormat=N3}" FontSize="30"/>
</StackPanel>
</Window>