.net - Metro 应用程序 (.NET) 中的受控非 UI 计时器

标签 .net timer windows-8 windows-runtime winrt-xaml

我需要一个计时器类,它应该提供启动/停止/启用/禁用的功能,并且应该是非 UI。

我看到 2 个选项

  • DispatcherTimer -> 具有除在 UI 线程上执行之外的所有功能
  • ThreadPoolTimer -> 无法控制周期性计时器。

  • 我正在考虑在线程池计时器上创建包装器,但似乎非常复杂,因为没有/有限控制它。

    如何为所述场景设计计时器类。 (我需要类似于 System.Threading.Timer 的东西)。

    最佳答案

    由于 UI 在 Metro 应用程序中应该非常敏感 - 运行 DispatcherTimer 并在您想要在后台线程上运行的事情上调用 Task.Run() 可能就足够了。

    如果这对您不起作用 - 看看这是否有效。它应该具有与 DispatcherTimer 类似的 API,但在不同的线程上运行。并不是说它一直在等待 Interval 集的持续时间,因此计时器将众所周知地迟到。它也不完全是线程安全的,我只玩了 10 分钟,所以它可能并不总是有效,但由于它是开源的 - 您可以修改它以适应您的需求。

    public class BackgroundTimer
    {
        private AutoResetEvent _stopRequestEvent;
        private AutoResetEvent _stoppedEvent;
    
        #region Interval
        private TimeSpan _interval;
        public TimeSpan Interval
        {
            get
            {
                return _interval;
            }
            set
            {
                if (IsEnabled)
                {
                    Stop();
                    _interval = value;
                    Start();
                }
                else
                {
                    _interval = value;
                }
            }
        }
        #endregion
    
        public event EventHandler<object> Tick;
    
        #region IsEnabled
        private bool _isEnabled;
        public bool IsEnabled
        {
            get
            {
                return _isEnabled;
            }
            set
            {
                if (_isEnabled == value)
                    return;
    
                if (value)
                    Start();
                else
                    Stop();
            }
        } 
        #endregion
    
        public BackgroundTimer()
        {
            _stopRequestEvent = new AutoResetEvent(false);
            _stoppedEvent = new AutoResetEvent(false);
        }
    
        public void Start()
        {
            if (_isEnabled)
            {
                return;
            }
    
            _isEnabled = true;
            _stopRequestEvent.Reset();
            Task.Run((Action)Run);
        }
    
        public void Stop()
        {
            if (!_isEnabled)
            {
                return;
            }
    
            _isEnabled = false;
            _stopRequestEvent.Set();
            _stoppedEvent.WaitOne();
        }
    
        private void Run()
        {
            while (_isEnabled)
            {
                _stopRequestEvent.WaitOne(_interval);
    
                if (_isEnabled &&
                    Tick != null)
                {
                    Tick(this, null);
                }
            }
    
            _stoppedEvent.Set();
        }
    }
    

    关于.net - Metro 应用程序 (.NET) 中的受控非 UI 计时器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10493253/

    相关文章:

    .NET 认为屏幕的顺序不同于 Windows 控制面板 |显示 |屏幕分辨率

    c# - DragDrop 事件之后是否有事件发生?

    c# - 带有附加列的sql批量插入

    java - 计时器到期后停止并启动新线程

    c# - Windows 8 和桌面应用程序

    c# - 需要工作流程编辑软件 - 推荐

    java - 秒表取消暂停不起作用

    c# - .NET 中定时器的最大精度是多少?

    c# - 使用 PostAsync、HttpClient 和 Json 从 C# Metro UI 客户端调用 MVC4 WebAPI 方法

    windows-8 - 我可以将图像作为数据 URI 嵌入到 Windows 8/10 Toast 通知中吗?