c# single threaded timer

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);
    }
}

The .NET Framework provides four timers. Two of these are general-purpose multithreaded timers:

  • System.Threading.Timer
  • System.Timers.Timer

The other two are special-purpose single-threaded timers:

  • System.Windows.Forms.Timer (Windows Forms timer)
  • System.Windows.Threading.DispatcherTimer (WPF timer)

The last 2 are designed to eliminate thread-safety issues for WPF and Windows Forms applications.

For example, using WebBrowser inside a timer to capture screenshots from webpage needs to be single-threaded and gives an error at runtime if it is on another thread.

The single-thread timers have the following benefits

  • You can forget about thread safety.
  • A fresh Tick will never fire until the previous Tick has finished processing.
  • You can update user interface elements and controls directly from Tick event handling code, without calling Control.BeginInvoke or Dispatcher.BeginIn voke.

and main disadvantage to note

  • One thread serves all timers—as well as the processing UI events. Which means that the Tick event handler must execute quickly, otherwise the user interface becomes unresponsive.

source: most are scraps from C# in a Nutshell book -> Chapter 22 -> Advanced threading -> Timers -> Single-Threaded Timers


For anyone who needs a single thread timer and wants to count interval after task done. System.Timers.Timer could do the trick without locking or [ThreadStatic]

System.Timers.Timer tmr;

void InitTimer(){
    tmr = new System.Timers.Timer();
    tmr.Interval = 300;
    tmr.AutoReset = false;
    tmr.Elapsed += OnElapsed;
}

void OnElapsed( object sender, System.Timers.ElapsedEventArgs e )
{
    backgroundWorking();

    // let timer start ticking
    tmr.Enabled = true;
}

Credit to Alan N source https://www.codeproject.com/Answers/405715/System-Timers-Timer-single-threaded-usage#answer2

Edit: spacing