using System; using System.ComponentModel; namespace Chernobyl.ComponentModel { /// /// A default implementation of the interface. This /// class is intended to make the creation of s easier. /// You should never use this class as part of your interface (like as an /// argument to a method) as not all instances will /// derive from this class. /// public abstract class Task : ITask { /// /// Initializes a new instance of the class. /// protected Task() : this(0) {} /// /// Initializes a new instance of the class. /// /// The percentage of work, from 0% to /// 100%, that has been completed on this task. protected Task(int progressPercentage) { ProgressPercentage = progressPercentage; } /// /// Cancels the work being done but only if it has not been canceled /// already and the has not /// reached 100%. If cancellation is successful, the /// event will be raised. Note that, when the work being done is on /// another thread, it is possible that the work will finish just as /// this method is invoked. /// public void Cancel() { if (IsCanceled == false && ProgressPercentage != 100) { IsCanceled = true; ProgressPercentage = 0; if(Canceled != null) Canceled(this, EventArgs.Empty); } } /// /// True if the task has been canceled, false if otherwise. /// public bool IsCanceled { get; private set; } /// /// The percentage of work, from 0% to 100%, that has been completed on /// this task. Note that setting this property will cause the /// event to be raised if the amount of /// change between the new value and the old value is not equal to zero. /// If the task is Canceled (i.e. is invoked) the /// value of this property will be set to zero by this . /// /// Thrown if the new /// is less than 0% or if the /// is over 100%. public int ProgressPercentage { get { return _progressPercentage; } protected set { if (value < 0) throw new ArgumentOutOfRangeException("value", "You must provide a positive value for the amount " + "of progress made."); if (value > 100) throw new ArgumentOutOfRangeException("value", "The ITask.ProgressPercentage cannot be over 100%."); int changeAmount = value - _progressPercentage; _progressPercentage = value; if(changeAmount != 0 && ProgressChanged != null) ProgressChanged(this, new ProgressChangedEventArgs(ProgressPercentage, null)); } } /// /// An event that is raised when the is invoked /// on this instance. Note that this event is only raised once, /// regardless of how many times is invoked. This /// event will not be invoked if the /// is at 100%. /// public event EventHandler Canceled; /// /// An event that is raised when the progress of the task has changed. /// public event ProgressChangedEventHandler ProgressChanged; /// /// An implementation of the interface that /// represents a minor task that is completed immediately. /// public static readonly ITask Simple = new SimpleTask(); /// /// Checks if the event has subscribers. /// /// True if the has subscribers, /// false if otherwise. protected bool ProgressChangedHasSubscribers() { return ProgressChanged != null; } /// /// Raises the event. Note that this /// method does not check if has subscribers /// so you must invoke to find /// out before invoking this method. /// /// The instance /// containing the event data. protected void RaiseProgressChanged(ProgressChangedEventArgs e) { ProgressChanged(this, e); } /// /// Checks if the event has subscribers. /// /// True if the has subscribers, false /// if otherwise. protected bool CanceledHasSubscribers() { return Canceled != null; } /// /// Raises the event. Note that this /// method does not check if has subscribers /// so you must invoke to find /// out before invoking this method. /// /// The instance containing the /// event data. protected void RaiseCanceled(EventArgs e) { Canceled(this, e); } /// /// The backing field to . /// int _progressPercentage; } /// /// A type that is used for the field. This type /// represents a minor task that is completed immediately. /// class SimpleTask : Task { /// /// Prevents a default instance of the class /// from being created. /// public SimpleTask() : base(100) { } } }