【发布时间】:2017-11-27 13:08:16
【问题描述】:
我正在尝试模拟时钟的行为。为此,我创建了一个Observable.Interval,它在指定的时间间隔后,将属性的值更新相同的时间量。该值是数据绑定到 GUI 的。
问题是:“时钟”的运行速度比预期的慢很多,也就是说,时钟值增加一秒需要超过一秒的时间。
所需的时间分辨率越精细(下面的 MILLIS_INTERVAL 的值),问题就越严重(我用 1、10、100 和 1000 的其他约数对其进行了测试,因为 TimeSpan.FromMilliseconds 被记录为具有最大分辨率为 1 毫秒)。
我希望 observable 回调异步运行,并定期触发,可能并行触发,尽管执行需要时间,但似乎频率越大,滞后越多。
视图模型
使用系统; 使用 System.ComponentModel; 使用 System.Reactive.Linq; 命名空间间隔时钟 { 公共类 ViewModel:INotifyPropertyChanged { 公共双 TimeSeconds { 得到 { 返回 _timeSeconds; } 放 { _timeSeconds = 值; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("TimeSeconds")); } } 双 _timeSeconds; 常量双 MILLIS_INTERVAL = 10; 公共视图模型() { Observable.Interval(TimeSpan.FromMilliseconds(MILLIS_INTERVAL)) .Subscribe(token => TimeSeconds += MILLIS_INTERVAL / 1000); } 公共事件 PropertyChangedEventHandler PropertyChanged; } }主窗口:
<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>
【问题讨论】:
-
@mm8 我该如何解决这个问题?
-
你的意思是让回调并行运行,彼此独立?
-
Windows 不是实时操作系统,因此计时器并不完美。你可能会有明显的漂移。此外,Windows 上的最小分辨率为 15.6 毫秒 - 因此,无论您做什么,任何小于此值的有效时间都是 15.6 毫秒。
-
@mm8 是的。我只是尝试将回调放在
Task.Run()中,但无济于事。 -
@mm8 - 计时器不在同一个线程上调用
OnNext。
标签: c# wpf mvvm system.reactive