RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1275282
Accepted
aepot
aepot
Asked:2022-04-27 07:20:00 +0000 UTC2022-04-27 07:20:00 +0000 UTC 2022-04-27 07:20:00 +0000 UTC

显示当前时间 - 每秒准确调用代理 1 次

  • 772

网上有很多关于如何在应用程序中显示当前时间的解决方案。有定时器和异步的解决方案。

但我发现的所有解决方案都存在一个问题——它们导致界面并非每秒更新一次。

  • 跳过几秒钟。对于那些将更新间隔设置为 1000 毫秒的人,调用发生的频率较低,因为计时器从上一个处理程序执行结束到下一个处理程序执行倒计时一秒。而不是每秒调用一次。当它到达改变秒值的边界时,时钟会变慢,跳过一秒,例如10:33:12 => 10:33:14。
  • 轮询。有更智能的解决方案,它们不是每秒更新一次屏幕上的时间,而是每秒更新 5 次甚至更多次。更新越频繁,屏幕上的时间就越相关。当从每秒更新 10 次及以上时,延迟结果是最大正负更新间隔,即每秒更新 10 次,秒数变化的间隔将从 0.9 秒到 1.1 秒,原则上,肉眼几乎察觉不到。但这是另一个负值 - 频繁的界面更新 + 频繁的系统时间请求会给系统带来额外的负载。

看起来任务看似简单,但我没有找到现成的解决方案,或者我看起来很糟糕。我决定自己写。

c#
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    aepot
    2022-04-27T07:20:00Z2022-04-27T07:20:00Z

    开发解决方案的要求如下:

    • 跨平台,不依赖于特定环境或应用程序类型。
    • 实现尽可能简单。

    这是解决方案:

    public class ClockTimer
    {
        private readonly Action<DateTime> _action;
        private CancellationTokenSource _cts;
    
        public ClockTimer(Action<DateTime> action) 
            => _action = action;
    
        public async void Start()
        {
            if (_cts != null)
                return;
            try
            {
                using (_cts = new CancellationTokenSource())
                {
                    while (true)
                    {
                        DateTime date = DateTime.Now;
                        _action(date);
                        await Task.Delay(1000 - date.Millisecond, _cts.Token);
                    }
                }
            }
            catch (OperationCanceledException) { }
            catch (Exception ex)
            {
                Debug.Fail(ex.ToString());
            }
            _cts = null;
        }
    
        public void Stop() 
            => _cts?.Cancel();
    }
    

    在这里,我用一块石头杀死了 2 只鸟:我每秒只调用一次更新,并且.001-.020мс在时钟上的秒数变化之后立即发生更新,并且我立即将已经从系统收到的日期传输给代表。实际偏差仅由异步成本产生。

    我像这样在WPF中目视检查

    ClockTimer clock = new ClockTimer(d => Text = d.ToString("HH:mm:ss.fff"));
    clock.Start();
    

    与更新托盘中的Windows系统时钟Text绑定并比较的属性在哪里。TextBlock分钟在同一时间更改,甚至在应用程序中更早更改。

    为了工作清晰,我还在控制台中对其进行了测试

    static void Main(string[] args)
    {
        ClockTimer clock = new ClockTimer(d => Console.WriteLine(d.ToString("HH:mm:ss.fff")));
        clock.Start();
        Console.ReadKey();
    }
    

    控制台输出

    02:10:25.431
    02:10:26.077
    02:10:27.019
    02:10:28.009
    02:10:29.011
    02:10:30.005
    02:10:31.021
    02:10:32.012
    02:10:33.011
    02:10:34.017
    02:10:35.009
    02:10:36.016
    02:10:37.014
    02:10:38.009
    

    如您所见,在启动后立即发生稳定,然后调用恰好每秒一次,尽可能接近时钟上的秒数变化。

    在系统延迟、CPU 过载或死机时,会尽快调用委托,然后像初始启动时一样再次稳定,这符合条件。即使您坚持使用委托本身,例如Thread.Sleep(500)暂停线程,调用仍将是每秒 1 次,尽管从时钟秒数变化的那一刻起延迟相同的 500 毫秒。

    • 3

相关问题

  • 使用嵌套类导出 xml 文件

  • 分层数据模板 [WPF]

  • 如何在 WPF 中为 ListView 手动创建列?

  • 在 2D 空间中,Collider 2D 挂在玩家身上,它对敌人的重量相同,我需要它这样当它们碰撞时,它们不会飞向不同的方向。统一

  • 如何在 c# 中使用 python 神经网络来创建语音合成?

  • 如何知道类中的方法是否属于接口?

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    表格填充不起作用

    • 2 个回答
  • Marko Smith

    提示 50/50,有两个,其中一个是正确的

    • 1 个回答
  • Marko Smith

    在 PyQt5 中停止进程

    • 1 个回答
  • Marko Smith

    我的脚本不工作

    • 1 个回答
  • Marko Smith

    在文本文件中写入和读取列表

    • 2 个回答
  • Marko Smith

    如何像屏幕截图中那样并排排列这些块?

    • 1 个回答
  • Marko Smith

    确定文本文件中每一行的字符数

    • 2 个回答
  • Marko Smith

    将接口对象传递给 JAVA 构造函数

    • 1 个回答
  • Marko Smith

    正确更新数据库中的数据

    • 1 个回答
  • Marko Smith

    Python解析不是css

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5