Click here to Skip to main content
15,896,468 members
Articles / Programming Languages / C#

Timer surprises, and how to avoid them

Rate me:
Please Sign up or sign in to vote.
4.82/5 (72 votes)
2 Feb 2007CPOL6 min read 200.8K   3.6K   98  
A simple app demonstrates unexpected behavior of .NET timers and Thread.Sleep(); native multimedia timers come to the rescue.
//*******************************************************************
// LP TimerTest
//
// a test application for .NET timers
//
// Copyright: Luc Pattyn, January 2007
//
// This code is freely available for any non-commercial use.
//
//*******************************************************************
using System;
using System.Text;
using System.Threading;

namespace TimerTest {
	// This class contains the Threading Timer experiment
	public class ThreadTimerTest {
		private Stringer logger;
		private System.Threading.Timer threadTimer;
		private int count;
		private int maxCount;
		private int interval;
		private DateTime start;
		private DateTime stop;

		public ThreadTimerTest(Stringer logger) {
			this.logger=logger;
		}

		private void log(string s) {
			if(logger!=null) logger(s);
		}

		public void Run(int maxCount, int interval) {
			count=0;
			this.maxCount=maxCount;
			this.interval=interval;
			log("Observing "+maxCount+" consecutive "+interval+" msec intervals for a System.Threading.Timer");
			threadTimer=new System.Threading.Timer(new TimerCallback(timerCallback),
				null, interval, interval);
			start=DateTime.Now;
			log("    start = "+start.ToString("HH:mm:ss.fff"));
		}

		private void timerCallback(object argNotUsed) {
			// warning: runs on another thread, so form.log and form.Done must be Invoked
			count++;
			if(count>=maxCount) {
				threadTimer.Dispose();
				stop=DateTime.Now;
				log("    stop  = "+stop.ToString("HH:mm:ss.fff"));
				log("    Thread Timer has finished");
				TimeSpan span=stop.Subtract(start);
				double msec=span.TotalMilliseconds;
				log("    got "+count+" ticks in "+msec+" msec");
				msec/=count;
				log("    average interval was "+msec+" msec");
				log("    but timer interval was "+interval+" msec");
				log("conclusions:");
				log(" - effective timer interval is not less than requested value");
				log(" - effective timer interval may be greater than requested value");
				log(" - effective timer interval corresponds to first multiple of");
				log("   system timer's period that is >= requested value");
				log("~");
			}
		}
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Belgium Belgium
I am an engineer with a background in electronics, software and mathematics.

I develop technical software, both for embedded systems and for desktop equipment. This includes operating systems, communication software, local networks, image processing, machine control, automation, etc.

I have been using all kinds of microcontrollers and microprocessors (Intel 4004/8080/8051/80386/Pentium, Motorola 680x/680x0/ColdFire/PowerPC, Microchip PIC, Altera NIOS, and many more), lots of programming languages (all relevant assemblers, Fortran, Basic, C, Java, C#, and many more), and different operating systems (both proprietary and commercial).

For desktop applications and general development tools I have been using both UNIX systems and Mac/MacOS for many years, but I have switched to x86-based PCs with Windows, Visual Studio and the .NET Framework several years ago.

I specialize in:
- cross-platform development (making software that runs on diverse hardware/OS combinations)
- instruction set simulation
- improving software performance, i.e. making sure the software runs the job at hand in as short a time as possible on the given hardware. This entails algorithm selection, implementation design, accurate measurements, code optimisation, and sometimes implementing virtual machines, applying SIMD technology (such as MMX/SSE), and more.

Comments and Discussions