Multi-thread cancel architecture, multi-thread Architecture
. NET 4.5 includes canceling the schema and allows you to cancel tasks that run for a long time in a standard way. Every blocked call should support this mechanism. But currently, not all blocking calls have implemented this new technology. Technologies that have implemented this mechanism include tasks (http://www.cnblogs.com/afei-24/p/6907840.html), concurrent collection classes (http://www.cnblogs.com/afei-24/p/6836976.html), parallel LINQ (http://www.cnblogs.com/afei-24/p/6860753.html), and several synchronization mechanisms.
Canceling an architecture is based on collaboration, and it is not mandatory. A long-running task checks whether it is canceled and returns control.
The method that supports cancellation accepts a CancellationToken parameter. This class defines the IsCancellationRequested attribute, in which long-running operations can check whether it should be terminated. Use the Register () method to Register a delegate that will be called when the System. Threading. CancellationToken is canceled. It is called when the Cancel () method is called to Cancel the operation.
1. Cancel the Parallel. For () method
The Parallel class provides an overloaded version of The For () method. In the overloaded version, you can pass ParallelOptions parameters. You can use the ParallelOptions type to pass a CancellationToken parameter. The CancellationToken parameter is generated by creating CancellationTokenSource. Because CancellationTokenSource implements the ICancelableOperation interface, you can use CancellationToken to register and use Cancle (), CancleAfter (), and other methods to cancel the operation.
Example:
static void CancelParallelFor() { var cts = new CancellationTokenSource(); cts.Token.Register( ()=> Console.WriteLine("token canceled!")); cts.CancelAfter(1000); try { ParallelLoopResult plr = Parallel.For(0, 100, new ParallelOptions { CancellationToken = cts.Token }, x => { Console.WriteLine("loop {0} started", x); Thread.Sleep(1000); Console.WriteLine("loop {0} fininshed!", x); }); } catch (OperationCanceledException ex) { Console.WriteLine(ex.Message); } }
Output:
In the For loop implementation code, the Parallel class verifies the CancellationToken result and cancels the operation. Once the operation is canceled, the For () method throws an OperationCanceledException type exception.
It can be seen from the output that when the operation is canceled, the started operation is allowed to be completed, because the cancellation operation is always performed in collaboration to avoid resource leakage during the cancellation iteration operation.
2. Cancel a task
Canceling a task is similar to canceling the Parallel. For () method. First, create a CancellationTokenSource. If you only need one unmark, you can access Task. Factory. CancellationToken to use the default unmark. The task accepts the unmark through the TaskFactory object. In the constructor, assign the unmark to TaskFactory. This unmark and task is used to check the IsCancellationRequested attribute of CancellationToken to determine whether the request is canceled.
Example:
Static void CancelTask () {var cts = new CancellationTokenSource (); cts. Token. Register () => Console. WriteLine ("task canceled! "); Cts. CancelAfter (2000); try {Task t = Task. Run () => {CancellationToken token = cts. Token; Console. WriteLine (" task stared! "); For (int I = 0; I <20; I ++) {Thread. Sleep (500); if (cts. IsCancellationRequested) {Console. WriteLine (" canceled! "); Token. ThrowIfCancellationRequested (); // throw an exception break;} Console. WriteLine (" in loop! ") ;}}, Cts. token); t. wait ();} catch (aggresponexception ex) {Console. writeLine ("exception: {0}, {1}", ex. getType (). name, ex. message); foreach (var innerEx in ex. innerExceptions) {Console. writeLine ("exception: {0}, {1}", ex. innerException. getType (). name, ex. innerException. message );}}}
Output: