Search

Advertising

Home Downloads Components

Components

Folder Path: \ Components \

File: High-Performance Task Scheduler

file.png
Uploaded:
June.08.09
Modified:
November.30.09
File Size:
13 KB
Downloads:
657
Version
1.0

High-performance task scheduler which can schedule callbacks to be performed at a specific time or after a certain amount of time has elapsed. Callbacks can be performed independently of whether the system clock is adjusted or can be triggered at the time following the adjustment. Time sources can be mocked so controllably advance time in unit tests and debugging sessions. Accurate and uses nearly no CPU power by itself.

Details

For a small utility I was writing for myself, I needed a way to schedule tasks to be executed at regular intervals. Something like Unix' Cron, which executes scripts and programs a predefined times, only faster and written in portable .NET code.

The logical choice would have been to just hook up the System.Threading.Timer class, but being the perfectionist I am, I had to re-implement the whole thing in C# with some extras. For once, I wanted it to be able to use DateTime values for notification. Another problem is that while System.Threading.Timer uses some native code magic to efficiently achieve its goal, it doesn't mix particularly well with unit tests. You don't want your unit tests wait for 5 seconds hoping that the System.Threading.Timer will tick at the expected time - write 100 tests of that kind and your tests will take nearly 10 minutes to run.

So I created a Cron-like scheduler which could use different time sources:

  • A generic time source that works on Windows, Linux and the XBox 360.
  • A windows-specific time source that makes use of Microsoft's SystemEvents class
  • A mocked time source that allows your tests to advance time manually

To keep the entire codebase as efficient as possible, I used a priority queue that sorts the scheduled callbacks by their due time. That way, I can simply let the Scheduler thread sleep until the due time is reached or until it is woken up for maintenance.

Example

This is what the API looks like now:

// Create a new scheduler (automatically selects best time source)
using(Scheduler scheduler = new Scheduler()) {

  // Schedule a notification in 3 seconds from now
  scheduler.NotifyAt(
    DateTime.UtcNow + TimeSpan.FromSeconds(3),
    delegate(object state) {
      Console.WriteLine("3 seconds have passed!");
    }
  );
  
  
  // Wait 5 seconds. The scheduler will invoke the code in the anonymous
  // delegate using a ThreadPool thread during this time.
  Thread.Sleep(TimeSpan.FromSeconds(5));

} // Scheduler lifetime ends here

Now I can test my code without having either ridiculously slow tests or adjusting the timings to values in the millisecond range which might cause random failures if the system load spikes whilst the unit test is running.

Features

  • Scheduling of callbacks with due times ranging from milliseconds to years
  • Configurable time sources, can use real-time, mocked time (for unit tests) or any custom time source you implement
  • 100% test coverage for the whole code base
  • Callbacks can be dependent on the system clock (so you can create callbacks that run exactly at 12 o'clock - even if the user adjusts the system's date/time)
  • Callbacks can have a relative due time (so you can create callbacks that will run in exactly 5 minutes - even if the user changes the system's date/time)
  • Works on Windows, Linux and the XBox 360
  • Cancelling of scheduled callbacks

The Scheduler class is part of the Nuclex.Support library from the Nuclex Framework. You can find the most recent release of the code on the framework's CodePlex site: http://nuclexframework.codeplex.com/



Joomla Template by Joomlashack