首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我能让这个TimerQueueTimer类更有表现力吗?

我能让这个TimerQueueTimer类更有表现力吗?
EN

Stack Overflow用户
提问于 2011-05-11 05:01:29
回答 1查看 1.2K关注 0票数 3
代码语言:javascript
复制
using System;
using System.Threading;

internal class TimerQueueTimer : IDisposable
{
    public TimerQueueTimer(int interval, int msBeforeFirstCall)
    {
        this.interval = interval;
        this.msBeforeFirstCall = msBeforeFirstCall;
        this.callback = this.ticked;
        this.isTheFirstTick = true;
        this.isStopped = true;
    }

    public event EventHandler Ticked;

    public void Start()
    {
        if (!this.isStopped)
        {
            return;
        }

        this.isTheFirstTick = true;
        this.isStopped = false;
        Computer.ChangeTimerResolutionTo(1);
        NativeMethods.CreateTimerQueueTimer(
            out this.handle,
            IntPtr.Zero,
            this.callback,
            IntPtr.Zero,
            (uint)this.msBeforeFirstCall,
            (uint)this.interval,
            CallbackExecution.ExecuteInTimerThread);
    }

    public void Stop()
    {
        if (this.isStopped)
        {
            return;
        }

        NativeMethods.DeleteTimerQueueTimer(
            IntPtr.Zero,
            this.handle,
            IntPtr.Zero);
        Computer.ClearTimerResolutionChangeTo(1);
        this.isStopped = true;
    }

    public void Dispose()
    {
        this.Stop();
    }

    private void ticked(IntPtr parameterPointer, bool timerOrWaitFired)
    {
        if (this.isStopped)
        {
            return;
        }

        if (this.isTheFirstTick)
        {
            Thread.CurrentThread.Priority = ThreadPriority.Highest;
        }

        this.isTheFirstTick = false;
        var ticked = this.Ticked;
        if (ticked != null)
        {
            ticked(this, EventArgs.Empty);
        }
    }

    private IntPtr handle;
    private volatile bool isStopped;
    private volatile bool isTheFirstTick;
    private readonly WaitOrTimerDelegate callback;
    private readonly int interval;
    private readonly int msBeforeFirstCall;
}

(注:Computer.ChangeTimerResolutionTo()Computer.ClearTimerResolutionChangeTo()分别调用timeBeginPeriodtimeEndPeriod。)

问题:

  1. 回调在计时器的线程中运行,而不是在ThreadPool线程中运行。只要回调函数快就行了,对吧?
  2. 将回调线程(因此是计时器线程)的优先级设置为最高优先级是否对性能有任何影响?
  3. 最好是让计时器间隔1ms,计数滴答数,提高Ticked如果tickCount % interval == 0?低间隔计时器是否更精确更精确?
  4. 是否有任何理由比类似地创建的timeSetEvent计时器更不准确和/或精确?

我之所以问这个问题,是因为我们遇到了计时器回调的问题,当系统负载很重时,计时器回调偶尔会被延迟多达50 is。与我们以前使用timeSetEvent时相比,感觉这种情况发生的频率要低一些--尽管这可能只是一种幻觉。我知道Windows不是确定性的,所以我只能做这么多。然而,我想确保我已经做了我能做的一切,使这尽可能高优先。还有什么我能做的吗?

EN

回答 1

Stack Overflow用户

发布于 2014-01-28 16:34:16

我使用优先级队列来解决这个问题:队列中的每个元素都包含回调地址(计时器例程),指向回调参数的指针,以及将来应该触发的时间。

“时间”是优先级,这里的逻辑是有可能从另一个线程唤醒计时器线程。当回调被另一个线程添加到队列中时,计时器线程将被唤醒并查找优先级队列的顶部元素,计算存储在队列中的当前时间和“时间”之间的差异,直到计算的超时超过为止。

当计时器线程被超时唤醒时,它从调用回调的线程池中启动新线程。

我有一个计时器队列实现这里,它没有经过很好的测试,但您可以查看它是否有用。

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

https://stackoverflow.com/questions/5959484

复制
相关文章

相似问题

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