4

I have found a number of great .NET scheduling engines, specifically Quartz.Net looks very promising. However, I need a scheduling engine that will allow me to trigger off of not only dates and times but also off of anything I can come up with. For example I might want to trigger when I see a process has started, when the computer is locked, off of a WMI event, etc... in addition to date/time based triggers.

What I am looking for is a solution that will allow me to implement the appropriate interface and fire the trigger whenever my conditions are met. Does something like this already exist or am I on my own?

Here are a couple I looked at:

This needs to run within my .NET application. I looked into modifying Quartz.Net to support this type of triggering but the concept of date/time triggers is just to ingrained; it would probably be easier to write my own scheduler since I don't need to save jobs and triggers to a database.

I'd prefer to work off of an existing scheduling system just so I don't have to worry about implementing the gritty details like queues, priorities, thread pools, etc... but of course I'll do what I have to do.

Community
  • 1
  • 1
Peter
  • 9,643
  • 6
  • 61
  • 108

1 Answers1

1

You could declare a base Task class, or interface, whichever you prefer that implements a bool property NeedsToRun and a method Run().

You could then inherit the Task class for each of your individual tasks (or using delegate funcs, task types) and define all the custom requirements you would need in order to check whether or not that task needs to run, and if it does, call the Run() method of that specific task.

Add all your tasks to a List<Task> and iterate over them periodically to see which task actually need running, and voila; you have a very simple, but effective scheduler.

Personally, I was after a priority-based scheduler rather than an event-driven one as you describe, so I implemented a Func<bool> to determine whether a task needs to run and an Action to actually run it. My code is as follows:

public class Task : IComparable<Task>
{
    public Task(int priority, Action action, Func<bool> needsToRun, string name = "Basic Task")
    {
        Priority = priority;
        Name = name;
        Action = action;
        _needsToRun = needsToRun;
    }

    public string Name { get; set; }

    public int Priority { get; set; }

    private readonly Func<bool> _needsToRun;

    public bool NeedsToRun { get { return _needsToRun.Invoke(); } }

    /// <summary>
    /// Gets or sets the action this task performs.
    /// </summary>
    /// <value>
    /// The action.
    /// </value>
    public Action Action { get; set; }

    public void Run()
    {
        if (Action != null)
            Action.Invoke();
    }

    #region Implementation of IComparable<in State>

    /// <summary>
    /// Compares the current object with another object of the same type.
    /// </summary>
    /// <returns>
    /// A value that indicates the relative order of the objects being compared. The return value has the following meanings: Value Meaning Less than zero This object is less than the <paramref name="other"/> parameter.Zero This object is equal to <paramref name="other"/>. Greater than zero This object is greater than <paramref name="other"/>. 
    /// </returns>
    /// <param name="other">An object to compare with this object.</param>
    public int CompareTo(Task other)
    {
        return Priority == other.Priority && Name == other.Name ? 1 : 0;
    }

    #endregion
}

But I reckon this could be adapted to subscribe to events and setting a flag to make sure NeedsToRun returns true whenever that event is fired fairly easily.

aevitas
  • 3,753
  • 2
  • 28
  • 39
  • This class might be a good starting point, and I appreciate you posting the code. If I go this route I'll let you know. – Peter Sep 07 '12 at 22:14