- stop an asynchronous operation to start a replacing one
- Task currentTask;
- CancellationTokenSource cancelTokenSource;
- CancellationToken cancelToken;
- Task newTask;
- CancellationTokenSource newCancelTokenSource;
- CancellationToken newCancelToken;
- public Form1()
- {
- InitializeComponent();
- }
- private void button1_Click(object sender, EventArgs e)
- {
- if(currentTask != null && currentTask.Status == TaskStatus.Running)
- {
- //Cancel the running task
- cancelTokenSource.Cancel();
- //Prepare a new Task to be triggered when the other cancels
- //You could store new tasks/tokens in a dictionary if you wanted,also
- //A new cancel token is always needed since the old stays cancelled
- newCancelTokenSource = new CancellationTokenSource();
- newCancelToken = newCancelTokenSource.Token;
- newTask = new Task(()=>LongRunningTask(), newCancelToken);
- //Continue that deals with both cancel and completion
- //There is a different way to deal with this below, also
- newTask.ContinueWith((previousTask)=>
- {
- if(previousTask.Status == TaskStatus.Cancelled)
- {
- label1.Text = "New Task Cancelled, Another New Starting";
- BeginNewTask();
- }
- else
- label1.Text = "New Task Ran To Completion";
- },
- //If cancelled token is passed, it will autoskip the continue
- new CancellationTokenSource().Token, TaskContinuationOptions.None,
- //This is to auto invoke the UI thread
- TaskScheduler.FromCurrentSynchronizationContext());
- }
- else
- {
- cancelTokenSource = new CancellationTokenSource();
- cancelToken = cancelTokenSource.Token;
- //Start a fresh task since none running
- currentTask = Task.Factory.StartNew(()=>LongRunningTask(),
- cancelToken);
- //OnCancelContinue
- currentTask.ContinueWith((previousTask)=>
- {
- label1.Text = "First Task Cancelled, New Starting";
- BeginNewTask();
- },
- //If cancelled token is passed, it will autoskip the continue
- new CancellationTokenSource().Token,
- TaskContinuationOptions.OnlyOnCancelled,
- //This is to auto invoke the UI thread
- TaskScheduler.FromCurrentSynchronizationContext());
- //OnCompleteContinue
- currentTask.ContinueWith((previousTask)=>
- {
- label1.Text = "First Task Ran To Completion";
- },
- //If cancelled token is passed, it will autoskip the continue
- new CancellationTokenSource().Token,
- TaskContinuationOptions.OnlyOnRanToCompletion,
- //This is to auto invoke the UI thread
- TaskScheduler.FromCurrentSynchronizationContext());
- }
- }
- private void LongRunningTask()
- {
- for(int i = 0; i < 60; i++)
- {
- if(cancelToken.IsCancellationRequested)
- cancelToken.ThrowIfCancellationRequested();
- Thread.Sleep(1000);
- }
- }
- private void BeginNewTask()
- {
- //Since the old task is cancelled, reset it with the new one
- //Probably should do some error checks
- currentTask = newTask;
- cancelTokenSource = newCancelTokenSource;
- cancelToken = newCancelToken;
- //This is to make sure this task does not run on the UI thread
- currentTask.Start(TaskScheduler.Default);
- }