. Net parallel programming series of Task cancellation,. nettask
During the Task running process, we can cancel the Task running through the built-in method in. Net 4.
To create a Task that can be canceled, you need to use the following objects:
1. System. Threading. CancellationTokenSource instance
CancellationTokenSource tokenSource = new CancellationTokenSource();
2. Get a cancellation Token through the CancellationTokenSource. Token attribute
CancellationToken token = tokenSource.Token;
3. Create a Task object and input it in the constructor.Action (or Action <T>)Delegate as the first parameter,CancellationTokenAs the second parameter(Important)
Task task = new Task(() =>{// do something}, token);
task.Start();
4. You can also create a Task object by calling the static method provided by the System. Threading. Tasks. TaskFactory class.
Task task = Task.Factory.StartNew(() =>{ // do something ......}, token);
To cancel a Task, you must callCancel ()In addition, the Action delegate also needs to check the canceled status of CancellationToken and write the corresponding code.(Throw an exception)To prevent tasks from running.
You can check the Task cancellation status in the following ways:
1. Check by pollingCancellationTokenUnmark. This operation is similar to the round-robin asynchronous operation.IAsyncResult. IsCompletedStatus, which is also determined in the loopCancellationToken. IsCancellationRequestedAttribute to check whether the Task is canceled. If it is True, an exception is thrown in the Action delegate to cancel running the Task.
Static void Main (string [] args) {CancellationTokenSource tokenSource = new CancellationTokenSource (); CancellationToken token = tokenSource. token; Task task = new Task () => {while (true) {if (token. isCancellationRequested) {// resource release operations and so on... throw new OperationCanceledException (token);} Console. write (". "); Thread. sleep (100) ;}}, token); Console. writeLine ("Task is Running. "); Console. writeLine ("Press anykey to cancel task. ");
Task. Start ();
Console. ReadKey (true); Console. WriteLine (); Console. WriteLine ("Cancelling task."); tokenSource. Cancel ();
Console. WriteLine ("Main method complete."); Console. WriteLine ("Press enter to finish."); Console. ReadLine ();}
If you do not need to release system resources, you can directly callCancellationToken. ThrowIfCancellationRequested ()The implementation is as follows:
[__DynamicallyInvokable]public void ThrowIfCancellationRequested(){ if (this.IsCancellationRequested) { this.ThrowOperationCanceledException(); }}
Example:
while (true){ token.ThrowIfCancellationRequested(); Console.Write("."); Thread.Sleep(100);}
2. PassDelegate)To check whether the Task is canceled.CancellationTokenIs called whenCancellationTokenSourceWhen sending a cancellation request, the Delegate will run. We can implement the notification function in the delegate method.
static void Main(string[] args){ CancellationTokenSource tokenSource = new CancellationTokenSource(); CancellationToken token = tokenSource.Token; Task task = new Task(() => { while (true) { token.ThrowIfCancellationRequested(); Console.Write("."); Thread.Sleep(100); } }, token); token.Register(() => { Console.WriteLine("The delegate is triggered."); }); Console.WriteLine("Task is Running."); Console.WriteLine("Press anykey to cancel task."); task.Start(); Console.ReadKey(true); Console.WriteLine(); Console.WriteLine("Cancelling task."); tokenSource.Cancel(); Console.WriteLine("Main method complete."); Console.WriteLine("Press enter to finish."); Console.ReadLine();}
3. UseWaitHandleTo check whether the Task is canceled.CancellationToken.WaitHandleOnWaitOne ()The method will stop the current thread from executing untilCancellationTokenWhen the cancel request flag is received, the Task thread blocked by the token will be released and continue execution.
Multiple Task instances use the sameCancellationTokenWhenCancellationTokenWhen the cancel request flag is received, all tasks that use the token in the constructor will be canceled.
static void Main(string[] args){ CancellationTokenSource tokenSource = new CancellationTokenSource(); CancellationToken token = tokenSource.Token; Task task = new Task(() => { while (true) { token.ThrowIfCancellationRequested(); Console.Write("."); Thread.Sleep(100); } }, token); Task task1 = new Task(() => { token.WaitHandle.WaitOne(); Console.WriteLine("WaitHandle released."); }, token); Console.WriteLine("Task is Running."); Console.WriteLine("Press anykey to cancel task."); task.Start(); task1.Start(); Console.ReadKey(true); Console.WriteLine(); Console.WriteLine("Cancelling task."); tokenSource.Cancel();
Console.WriteLine("Main method complete."); Console.WriteLine("Press enter to finish."); Console.ReadLine();}
4.IsCancelledAttribute to determine whether the Task is canceled. If the constructor does not input the CancellationToken object during Task instantiation, the value obtained through the Task. IsCanceled attribute after the Task is canceled is stillFalseInsteadTrue.Task. ContinueWith ()If the method is not passed inCancellationTokenObject, the Task continues to be executed even if it is canceled.Task. ContinueWith ()The Action Delegate of the method.CancellationTokenObject, after the Task is canceledTask. ContinueWith ()The Action delegate in the method will not continue execution.
{ CancellationTokenSource tokenSource = new CancellationTokenSource(); CancellationToken token = tokenSource.Token; Task task = new Task(() => { try { Console.WriteLine("Task: Running"); Thread.Sleep(5000); Console.WriteLine("Task: ThrowIfCancellationRequested"); token.ThrowIfCancellationRequested(); Thread.Sleep(2000); Console.WriteLine("Task: Completed"); } catch (Exception exception) { Console.WriteLine("Task: " + exception.GetType().Name); throw; } }, token); task.ContinueWith(t => Console.WriteLine("ContinueWith: tokenSource.IsCancellationRequested = {0}, task.IsCanceled = {1}, task.Exception = {2}", tokenSource.IsCancellationRequested, t.IsCanceled, t.Exception == null ? "null" : t.Exception.GetType().Name)); task.Start(); Thread.Sleep(1000); Console.WriteLine("Main: Cancel"); tokenSource.Cancel(); try { Console.WriteLine("Main: Wait"); task.Wait(); } catch (Exception exception) { Console.WriteLine("Main: Catch " + exception.GetType().Name); } Console.WriteLine("Main: task.IsCanceled = {0}", task.IsCanceled); Console.WriteLine("Press any key to exit..."); Console.ReadKey(true);}