I have a task that looks like this:
var task = Task.Factory.StartNew
I understand that you cannot cancel your long running task but want the process to be instantly aborted from the users point of view when he cancels.
Start a cancel task in parallel with your long running task. Continue off of Task.WhenAny(longRunningTask, cancelTask)
and check, if the completed task was the long running task or the cancel task. You can then decide what to do (show results or update UI).
When you cancel the "cancel task" the continuation will instantly fire.
I personally find the following approach to be the most elegant:
// Cancellation token for the latest task.
private CancellationTokenSource cancellationTokenSource;
private void OnClick(object sender, ItemClickEventArgs e)
{
// If a cancellation token already exists (for a previous task),
// cancel it.
if (this.cancellationTokenSource != null)
this.cancellationTokenSource.Cancel();
// Create a new cancellation token for the new task.
this.cancellationTokenSource = new CancellationTokenSource();
CancellationToken cancellationToken = this.cancellationTokenSource.Token;
// Start the new task.
var task = Task.Factory.StartNew<object>(LongMethod, cancellationToken);
// Set the task continuation to execute on UI thread,
// but only if the associated cancellation token
// has not been cancelled.
task.ContinueWith(TaskCallback,
cancellationToken,
TaskContinuationOptions.NotOnCanceled,
TaskScheduler.FromCurrentSynchronizationContext());
}
private void TaskCallback(Task<object> task)
{
// Just update UI
}