首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >System.Timers.Timer口吃

System.Timers.Timer口吃
EN

Stack Overflow用户
提问于 2022-06-25 17:10:26
回答 1查看 66关注 0票数 -1

在我的WinUI 3.0应用程序,我有一个秒表,每秒钟计数。通常,但不总是,它结巴时,计数。例如,计时器将停留在0:00:04,超过一秒钟,然后跳到0:00:06。

我做错什么了吗?

我的代码:

代码语言:javascript
复制
public static DateTime startTime;
private readonly System.Timers.Timer timer = new(1000);

public MainPage()
{ 
    ViewModel = App.GetService<MainViewModel>();
    this.InitializeComponent();
    
    timer.AutoReset = true;
    timer.Elapsed += Timer_Tick;
}

private void StartButton_Click(object sender, RoutedEventArgs e)
{
    if (!timer.Enabled)
    {
        startTime = DateTime.Now;
        timer.Start();
    } 
    else
    {
        DateTime stopTime = DateTime.Now;
        timer.Stop();
        timerLabel.Text = "0:00:00";
    }
}

private void Timer_Tick(object sender, EventArgs e)
{
    DispatcherQueue.TryEnqueue(() => 
    { 
        timerLabel.Text = DateTime.Now.Subtract(startTime).ToString(@"h\:mm\:ss"); 
    });

}
EN

回答 1

Stack Overflow用户

发布于 2022-06-25 18:23:55

一种方法(我自己解决这个问题的方法)是让我自己的系统计时器循环以更高的分辨率(0.1秒)触发,而不是根据计时器滴答来更新时钟显示,它使用PropertyChanged事件来更新Second,这个事件只作为PushDT方法的一个函数发生。我相信你可以用这个可靠的每秒一次的事件来编写另一个秒表。

这是一个共享的代码库,用于我的应用程序的PC、安卓和iOS版本,所以我有信心推荐它。不过,这只是“一条路”。

代码语言:javascript
复制
static class SystemTimer
{
    static SystemTimer()
    {
        Task.Run(async() => 
        {
            while (!_dispose)
            {
                PushDT(DateTime.Now);
                await Task.Delay(100); 
            }
        });
    }

PushDT基于PushDT更新可绑定的MinuteSecond属性。

代码语言:javascript
复制
    public static void PushDT(DateTime now)
    {
        // Using a 'now' that doesn't change within this method:
        Second = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second, now.Kind);
        Minute = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, 0, now.Kind);
    }
    public static event PropertyChangedEventHandler PropertyChanged;
    static DateTime _second = DateTime.MinValue;
    public static DateTime Second
    {
        get => _second;
        set
        {
            if(_second != value)
            {
                _second = value;
                PropertyChanged?.Invoke(nameof(SystemTimer), new PropertyChangedEventArgs(nameof(Second)));
            }
        }
    }
}

当(仅当) Second属性更改为“新秒”时,它会为Second触发一个属性更改,该属性将更新显示。需要注意的一点是,当更新UI时,需要将事件编组到UI线程上,而这取决于平台( SystemTimer类本身是可移植的)。

UI线程必须承受极大的负担才能跳过。我希望这个建议能帮助你达到你想要的结果。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72755825

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档