using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace HeliosPlus { using System; using System.Threading; using System.Threading.Tasks; /// /// A class used by Tasks to report progress or completion updates back to the UI. /// public sealed class ProgressReporter { /// /// The underlying scheduler for the UI's synchronization context. /// private readonly TaskScheduler scheduler; /// /// Initializes a new instance of the class. /// This should be run on a UI thread. /// public ProgressReporter() { this.scheduler = TaskScheduler.FromCurrentSynchronizationContext(); } /// /// Gets the task scheduler which executes tasks on the UI thread. /// public TaskScheduler Scheduler { get { return this.scheduler; } } /// /// Reports the progress to the UI thread. This method should be called from the task. /// Note that the progress update is asynchronous with respect to the reporting Task. /// For a synchronous progress update, wait on the returned . /// /// The action to perform in the context of the UI thread. /// Note that this action is run asynchronously on the UI thread. /// The task queued to the UI thread. public Task ReportProgressAsync(Action action) { return Task.Factory.StartNew(action, CancellationToken.None, TaskCreationOptions.None, this.scheduler); } /// /// Reports the progress to the UI thread, and waits for the UI thread to process /// the update before returning. This method should be called from the task. /// /// The action to perform in the context of the UI thread. public void ReportProgress(Action action) { this.ReportProgressAsync(action).Wait(); } /// /// Registers a UI thread handler for when the specified task finishes execution, /// whether it finishes with success, failiure, or cancellation. /// /// The task to monitor for completion. /// The action to take when the task has completed, in the context of the UI thread. /// The continuation created to handle completion. This is normally ignored. public Task RegisterContinuation(Task task, Action action) { return task.ContinueWith(_ => action(), CancellationToken.None, TaskContinuationOptions.None, this.scheduler); } /// /// Registers a UI thread handler for when the specified task finishes execution, /// whether it finishes with success, failiure, or cancellation. /// /// The type of the task result. /// The task to monitor for completion. /// The action to take when the task has completed, in the context of the UI thread. /// The continuation created to handle completion. This is normally ignored. public Task RegisterContinuation(Task task, Action action) { return task.ContinueWith(_ => action(), CancellationToken.None, TaskContinuationOptions.None, this.scheduler); } /// /// Registers a UI thread handler for when the specified task successfully finishes execution. /// /// The task to monitor for successful completion. /// The action to take when the task has successfully completed, in the context of the UI thread. /// The continuation created to handle successful completion. This is normally ignored. public Task RegisterSucceededHandler(Task task, Action action) { return task.ContinueWith(_ => action(), CancellationToken.None, TaskContinuationOptions.OnlyOnRanToCompletion, this.scheduler); } /// /// Registers a UI thread handler for when the specified task successfully finishes execution /// and returns a result. /// /// The type of the task result. /// The task to monitor for successful completion. /// The action to take when the task has successfully completed, in the context of the UI thread. /// The argument to the action is the return value of the task. /// The continuation created to handle successful completion. This is normally ignored. public Task RegisterSucceededHandler(Task task, Action action) { return task.ContinueWith(t => action(t.Result), CancellationToken.None, TaskContinuationOptions.OnlyOnRanToCompletion, this.Scheduler); } /// /// Registers a UI thread handler for when the specified task becomes faulted. /// /// The task to monitor for faulting. /// The action to take when the task has faulted, in the context of the UI thread. /// The continuation created to handle faulting. This is normally ignored. public Task RegisterFaultedHandler(Task task, Action action) { return task.ContinueWith(t => action(t.Exception), CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, this.Scheduler); } /// /// Registers a UI thread handler for when the specified task becomes faulted. /// /// The type of the task result. /// The task to monitor for faulting. /// The action to take when the task has faulted, in the context of the UI thread. /// The continuation created to handle faulting. This is normally ignored. public Task RegisterFaultedHandler(Task task, Action action) { return task.ContinueWith(t => action(t.Exception), CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, this.Scheduler); } /// /// Registers a UI thread handler for when the specified task is cancelled. /// /// The task to monitor for cancellation. /// The action to take when the task is cancelled, in the context of the UI thread. /// The continuation created to handle cancellation. This is normally ignored. public Task RegisterCancelledHandler(Task task, Action action) { return task.ContinueWith(_ => action(), CancellationToken.None, TaskContinuationOptions.OnlyOnCanceled, this.Scheduler); } /// /// Registers a UI thread handler for when the specified task is cancelled. /// /// The type of the task result. /// The task to monitor for cancellation. /// The action to take when the task is cancelled, in the context of the UI thread. /// The continuation created to handle cancellation. This is normally ignored. public Task RegisterCancelledHandler(Task task, Action action) { return task.ContinueWith(_ => action(), CancellationToken.None, TaskContinuationOptions.OnlyOnCanceled, this.Scheduler); } } }