Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to understand the cancellation of Task in NET 4 parallel programming

2025-01-27 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

How to understand. NET 4 parallel programming in Task cancellation, many novices are not very clear about this, in order to help you solve this problem, the following editor will explain in detail for you, people with this need can come to learn, I hope you can get something.

Because Task is the core class of .NET 4 parallel programming and the class we often deal with in parallel programming, it is necessary to have a comprehensive understanding of Task.

The editor mainly talks about how to cancel a task.

A standardized operation in TPL is to "cancel Task". The reason why it is a standardized operation is to compare this operation with traditional multithreaded programming.

In previous multithreaded programming, we usually wrote some code to cancel the running of the thread. But the method of canceling is built into the TPL of .NET 4, and maybe we don't think it's necessary for TPL to build this code because it's too simple. But this built-in approach not only cancels the running Task, but also reduces some of the risks that may arise when canceling the running Task, which we will discuss in more detail in a later article.

To create a canceled Task, you usually take the following steps:

a. Create an instance of System.Threading.CancellationTokenSource:

/ / create the cancellation token source ancellationTokenSource tokenSource = new CancellationTokenSource ()

b. Get a System.Threading.CancellationToken through the CancellationTokenSource.Token attribute:

CancellationToken token = tokenSource.Token

c. Create a new Task or Task, and pass the delegate of Action or Action as the * * parameter in the constructor and CancellationToken as the second parameter:

Task task = new Task (new Action (printMessage), token)

d. Call the Start () method of Task.

The above steps are almost the same as the code we described earlier to create a Task, except that one more parameter is passed in the constructor.

If you want to cancel the running of a Task, simply call the Cancel () method of the CancellationToken instance.

It is important to note that when we call the Cancel () method, .NET Framework does not force to shut down the running Task.

We have to detect the CancellationToken that was passed in when we created the Task ourselves.

When we create the Task, we pass the CancellationToken to the constructor. In fact, this CancellationToken is used by the .NET Framework to prevent us from running the cancelled Task again, which can be said to be a flag bit.

First of all, let's move on to the following topics:

1. Detect whether Task is canceled by polling

Loops are included within many Task to process data. We can detect whether the task has been canceled through the IsCancellationRequest property of the CancellationToken in the loop. If this property is true, then we have to jump out of the loop and release the resources occupied by task (such as database resources, file resources, etc.).

We can also cancel the running task by throwing System.Threading.OperationCanceledException in the task runtime.

The code is as follows:

Code

While (true) {if (token.IsCancellationRequested) {/ / tidy up and release resources throw new OperationCanceledException (token);} else {/ / do a unit of work}}

If we don't have any resources to release, simply call the CancellationToken.ThrowIfCancellationRequested () method, which checks to see if we want to cancel the task and throws an exception. The code is as follows:

While (true) token.ThrowIfCancellationRequested (); / / do a unit of work}

Here is a complete example: create a cancelable task and constantly check whether to cancel the task through polling

The code is as follows:

Code

Static void Main (string [] args) {/ / create the cancellation token source CancellationTokenSource tokenSource = new CancellationTokenSource (); / / create the cancellation token CancellationToken token = tokenSource.Token; / / create the task Task task = new Task (() = > {for (int I = 0; I)

< int.MaxValue; i++) { if (token.IsCancellationRequested) { Console.WriteLine("Task cancel detected"); throw new OperationCanceledException(token); } else { Console.WriteLine("Int value {0}", i); } } }, token); // wait for input before we start the task Console.WriteLine("Press enter to start task"); Console.WriteLine("Press enter again to cancel task"); Console.ReadLine(); // start the task task.Start(); // read a line from the console. Console.ReadLine(); // cancel the task Console.WriteLine("Cancelling task"); tokenSource.Cancel(); // wait for input before exiting Console.WriteLine("Main method complete. Press enter to finish."); Console.ReadLine(); } 2. 用委托delegate来检测Task是否被取消 我们可以在注册一个委托到CancellationToken中,这个委托的方法在CancellationToken.Cancel()调用之前被调用。 我们可以用这个委托中的方法来作为一个检测task是否被取消的另外一个可选的方法,因为这个方法是在Cancel()方法被调用之前就调用的,所以这个委托中的方法可以检测task是否被cancel了,也就是说,只要这个委托的方法被调用,那么就说这个CancellationToken.Cancel()方法被调用了,而且在这个委托的方法中我们可以做很多的事情,如通知用户取消操作发生了。 下面的代码给出了一个例子。 代码 static void Main(string[] args) { // create the cancellation token source CancellationTokenSource tokenSource = new CancellationTokenSource(); // create the cancellation token CancellationToken token = tokenSource.Token; // create the task Task task = new Task(() =>

{for (int I = 0; I)

< int.MaxValue; i++) { if (token.IsCancellationRequested) { Console.WriteLine("Task cancel detected"); throw new OperationCanceledException(token); } else { Console.WriteLine("Int value {0}", i); } } }, token); // register a cancellation delegate token.Register(() =>

{Console.WriteLine ("> Delegate Invoked\ n");}); / / wait for input before we start the task Console.WriteLine ("Press enter to start task"); Console.WriteLine ("Press enter again to cancel task"); Console.ReadLine (); / / start the task task.Start () / / read a line from the console. Console.ReadLine (); / / cancel the task Console.WriteLine ("Cancelling task"); tokenSource.Cancel (); / / wait for input before exiting Console.WriteLine ("Main method complete. Press enter to finish."); Console.ReadLine ();}

3. Wait Handle is also used to detect whether Task is cancelled.

The third way to detect whether task is cancel is to call the CancellationToken.WaitHandle attribute. The detailed use of this attribute will be discussed in more detail in subsequent articles, and the main thing to know here is that the WaitOne () method of CancellationToken blocks the operation of task, which is released only after the cancel () method of CancellationToken is called.

In the following example, two task are created, where task2 calls the WaitOne () method, so task2 will never run unless the Cancel () method of CancellationToken is called, so the WaitOne () method is also a way to detect whether task is cancel.

Code

Static void Main (string [] args) {/ / create the cancellation token source CancellationTokenSource tokenSource = new CancellationTokenSource (); / / create the cancellation token CancellationToken token = tokenSource.Token; / / create the task Task task1 = new Task (() = > {for (int I = 0; I)

< int.MaxValue; i++) { if (token.IsCancellationRequested) { Console.WriteLine("Task cancel detected"); throw new OperationCanceledException(token); } else { Console.WriteLine("Int value {0}", i); } } }, token); // create a second task that will use the wait handle Task task2 = new Task(() =>

{/ / wait on the handle token.WaitHandle.WaitOne (); / / write out a message Console.WriteLine ("> Wait handle released");}); / / wait for input before we start the task Console.WriteLine ("Press enter to start task") Console.WriteLine ("Press enter again to cancel task"); Console.ReadLine (); / / start the tasks task1.Start (); task2.Start (); / / read a line from the console. Console.ReadLine (); / / cancel the task Console.WriteLine ("Cancelling task"); tokenSource.Cancel (); / / wait for input before exiting Console.WriteLine ("Main method complete. Press enter to finish."); Console.ReadLine ();}

4. Cancel multiple Task

We can use a CancellationToken to create multiple different Tasks, and when the Cancel () method of this CancellationToken is called, multiple task that use this token will be canceled.

Code

Static void Main (string [] args) {/ / create the cancellation token source CancellationTokenSource tokenSource = new CancellationTokenSource (); / / create the cancellation token CancellationToken token = tokenSource.Token; / / create the tasks Task task1 = new Task (() = > {for (int I = 0; I)

< int.MaxValue; i++) { token.ThrowIfCancellationRequested(); Console.WriteLine("Task 1 - Int value {0}", i); } }, token); Task task2 = new Task(() =>

{for (int I = 0; I)

< int.MaxValue; i++) { token.ThrowIfCancellationRequested(); Console.WriteLine("Task 2 - Int value {0}", i); } }, token); // wait for input before we start the tasks Console.WriteLine("Press enter to start tasks"); Console.WriteLine("Press enter again to cancel tasks"); Console.ReadLine(); // start the tasks task1.Start(); task2.Start(); // read a line from the console. Console.ReadLine(); // cancel the task Console.WriteLine("Cancelling tasks"); tokenSource.Cancel(); // wait for input before exiting Console.WriteLine("Main method complete. Press enter to finish."); Console.ReadLine(); } 5. 创建组合的取消Task的Token 我们可以用CancellationTokenSource.CreateLinkedTokenSource()方法来创建一个组合的token,这个组合的token有很多的CancellationToken组成。主要组合token中的任意一个token调用了Cancel()方法,那么使用这个组合token的所有task就会被取消。代码如下: 代码 static void Main(string[] args) { // create the cancellation token sources CancellationTokenSource tokenSource1 = new CancellationTokenSource(); CancellationTokenSource tokenSource2 = new CancellationTokenSource(); CancellationTokenSource tokenSource3 = new CancellationTokenSource(); // create a composite token source using multiple tokens CancellationTokenSource compositeSource = CancellationTokenSource.CreateLinkedTokenSource( tokenSource1.Token, tokenSource2.Token, tokenSource3.Token); // create a cancellable task using the composite token Task task = new Task(() =>

{/ / wait until the token has been cancelled compositeSource.Token.WaitHandle.WaitOne (); / / throw a cancellation exception throw new OperationCanceledException (compositeSource.Token);}, compositeSource.Token); / / start the task task.Start () / / cancel one of the original tokens tokenSource2.Cancel (); / / wait for input before exiting Console.WriteLine ("Main method complete. Press enter to finish. "); Console.ReadLine ();}

6. Determine whether a Task has been cancelled

You can use the IsCancelled property of Task to determine whether the task has been cancelled. The code is as follows:

Code

Static void Main (string [] args) {/ / create the cancellation token source CancellationTokenSource tokenSource1 = new CancellationTokenSource (); / / create the cancellation token CancellationToken token1 = tokenSource1.Token; / / create the first task, which we will let run fully Task task1 = new Task (() = > {for (int I = 0; I)

< 10; i++) { token1.ThrowIfCancellationRequested(); Console.WriteLine("Task 1 - Int value {0}", i); } }, token1); // create the second cancellation token source CancellationTokenSource tokenSource2 = new CancellationTokenSource(); // create the cancellation token CancellationToken token2 = tokenSource2.Token; // create the second task, which we will cancel Task task2 = new Task(() =>

{for (int I = 0; I < int.MaxValue; iTunes +) {token2.ThrowIfCancellationRequested (); Console.WriteLine ("Task 2-Int value {0}", I);}, token2); / / start all of the tasks task1.Start () Task2.Start (); / / cancel the second token source tokenSource2.Cancel (); / / write out the cancellation detail of each task Console.WriteLine ("Task 1 cancelled? {0}", task1.IsCanceled); Console.WriteLine ("Task 2 cancelled? {0}", task2.IsCanceled) / / wait for input before exiting Console.WriteLine ("Main method complete. Press enter to finish. "); Console.ReadLine ();} is it helpful for you to read the above content? If you want to know more about the relevant knowledge or read more related articles, please follow the industry information channel, thank you for your support.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report