Silverlight中System.Timers.Timer的精确、多线程等效项

本文关键字:多线程 System Timers Timer Silverlight | 更新日期: 2023-09-27 18:20:41

我在WPF应用程序中使用System.Timers.Timer编写了以下代码,并希望移植到Silverlight。在WPF中,计时器用于轮询高性能可视化组件的数据更新,因此UI线程正在耗尽。

    private System.Timers.Timer _timer;
    private const int TimerInterval = 10; 
    private void Start()
    {
        _timer = new Timer(TimerInterval);            
        _timer.Elapsed += OnTick;
        _timer.AutoReset = true;   
        _timer.Start();            
    }
    private void OnTick(object sender, EventArgs e) { } // ... 

具体要求如下:

我有一个使用System.Timers.Timer的WPF应用程序,它从外部硬件读取/缓冲数据每10ms进行一次预处理,然后加载到可视化组件中。客户端希望看到此组件的Silverlight版本的演示以便以相同的速率脱机查看数据。

复制相同行为我创建了一个演示,其中每10ms并推入可视化组件。定时器会滴答作响,但由于UI工作很努力,GUI会断断续续。GUI可以处理更新率,只需从文件中读取/预处理该数据其需要以尽可能接近100Hz的速率进行多线程处理。

简而言之,无论OnTick处理程序的持续时间如何,我都希望计时器会周期性地启动,直到停止,并尽可能接近10ms。Ontick处理程序也应该出现在线程池(或后台)线程上,以允许以多线程方式读取/处理数据。

我看到Silverlight中有一个System.Threading.Timer,但不确定它的用法以及它与Timers.Timer版本的区别。

有人能为上述Timer代码提供一个良好的Silverlight端口或实现上述要求的解决方案吗?

欢迎评论/建议。

致问候,

Silverlight中System.Timers.Timer的精确、多线程等效项

我从msdn论坛收到了以下answe3r

一种方法是使用动画计时器而不是System.Threading计时器。这里有几个博客文章描述它…

http://blogs.msdn.com/jstegman/archive/2007/05/05/mix-createfromxaml-and-timer-sample.aspx

http://www.andybeaulieu.com/Home/tabid/67/EntryID/70/Default.aspx

在实际操作中,我使用了System.Threading.Timer并将其包装以创建与SilverlightTimer类似的API。这对我的情况很有帮助,因为我将代码双重部署到WPF和SL,因此我不仅在寻找功能等效的代码,而且在理想情况下,我可以在这两种场景中使用代码。

下面的测试是有效的,但没有提供System.Timers.Timer的所有功能(例如同步)。如果有人愿意的话,我相信使用Dispatcher添加不会太困难!

我在这里写过关于这一点的博客(以及Stopwatch的替代品)。

感谢您的评论&不管怎样,我们非常感谢您的建议。

致问候,

namespace System.Timers
{
    /// <summary>
    /// Drop in Silverlight compatible replacement for the System.Timers.Timer
    /// Doesn't do synchronisation
    /// </summary>
    public class Timer
    {
        private readonly uint _interval;
        private System.Threading.Timer _internalTimer;
        private const uint MaxTime = (uint)0xFFFFFFFD;
        public event EventHandler<EventArgs> Elapsed;
        public Timer(uint interval)
        {
            _interval = interval;
        }
        public bool AutoReset { get; set; }        
        public void Start()
        {
            Stop();
            _internalTimer = CreateTimer();            
        }        
        public void Stop()
        {
            if (_internalTimer != null)
            {
                _internalTimer.Change(MaxTime, MaxTime);
                _internalTimer.Dispose();
                _internalTimer = null;
            }
        }
        private Threading.Timer CreateTimer()
        {
            var timer = new System.Threading.Timer(InternalTick);
            timer.Change(_interval, AutoReset ? _interval : MaxTime);
            return timer;
        }
        private void InternalTick(object state)
        {
            var handler = Elapsed;
            if (handler != null)
            {
                handler(this, EventArgs.Empty);
            }
        }
    }
}