C#单线程计时器 [英] c# single threaded timer

查看:260
本文介绍了C#单线程计时器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想要一个具有以下属性的计时器:

I wanted a timer with the following properties:

  1. 无论调用多少次启动,都只会运行一个回调线程

  1. No matter how many times start is called, only one call back thread is ever running

关于时间间隔,忽略了回叫功能中花费的时间.例如,如果间隔为100毫秒,并且执行回调需要4000毫秒,则回调将在100毫秒,4100毫秒等时间内被调用.

The time spent in the call back function was ignored with regards to the interval. E.g if the interval is 100ms and the call back takes 4000ms to execute, the callback is called at 100ms, 4100ms etc.

我看不到任何可用的内容,因此编写了以下代码.有一个更好的方法吗?

I couldn't see anything available so wrote the following code. Is there a better way to do this?

/**
 * Will ensure that only one thread is ever in the callback
 */
public class SingleThreadedTimer : Timer
{
    protected static readonly object InstanceLock = new object();

    //used to check whether timer has been disposed while in call back
    protected bool running = false;

    virtual new public void Start()
    {
        lock (InstanceLock)
        {
            this.AutoReset = false;
            this.Elapsed -= new ElapsedEventHandler(SingleThreadedTimer_Elapsed);
            this.Elapsed += new ElapsedEventHandler(SingleThreadedTimer_Elapsed);
            this.running = true;
            base.Start();
        }

    }

    virtual public void SingleThreadedTimer_Elapsed(object sender, ElapsedEventArgs e)
    {
        lock (InstanceLock)
        {
            DoSomethingCool();

            //check if stopped while we were waiting for the lock, we don't want to restart if this is the case..
            if (running)
            {
                this.Start();
            }
        }
    }

    virtual new public void Stop()
    {
        lock (InstanceLock)
        {
            running = false;
            base.Stop();
        }
    }
}

推荐答案

下面是我刚刚提出的一个简单示例;

Here's a quick example I just knocked up;

using System.Threading;
//...
public class TimerExample
{
    private System.Threading.Timer m_objTimer;
    private bool m_blnStarted;
    private readonly int m_intTickMs = 1000;
    private object m_objLockObject = new object();

    public TimerExample()
    {
        //Create your timer object, but don't start anything yet
        m_objTimer = new System.Threading.Timer(callback, m_objTimer, Timeout.Infinite, Timeout.Infinite);
    }

    public void Start()
    {
        if (!m_blnStarted)
        {
            lock (m_objLockObject)
            {
                if (!m_blnStarted) //double check after lock to be thread safe
                {
                    m_blnStarted = true;

                    //Make it start in 'm_intTickMs' milliseconds, 
                    //but don't auto callback when it's done (Timeout.Infinite)
                    m_objTimer.Change(m_intTickMs, Timeout.Infinite);
                }
            }
        }
    }

    public void Stop()
    {
        lock (m_objLockObject)
        {
            m_blnStarted = false;
        }
    }

    private void callback(object state)
    {
        System.Diagnostics.Debug.WriteLine("callback invoked");

        //TODO: your code here
        Thread.Sleep(4000);

        //When your code has finished running, wait 'm_intTickMs' milliseconds
        //and call the callback method again, 
        //but don't auto callback (Timeout.Infinite)
        m_objTimer.Change(m_intTickMs, Timeout.Infinite);
    }
}

这篇关于C#单线程计时器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆