157 recommendations for writing high-quality code to improve C # programs--recommendation 80: Replace ThreadPool with Task

Source: Internet
Author: User

Recommendation 80: Replace ThreadPool with Task

ThreadPool has many advantages over thread, but there are some inconvenient threadpool in use. Like what:

ThreadPool does not support interactive operations such as thread cancellation, completion, failure notification, and so on.

ThreadPool does not support the prioritization of thread execution.

In the past, developers needed to do a lot of extra work if they wanted to implement the above features. Now, the FCL provides a more powerful concept: Task. The task online pool is optimized based on and provides more APIs. In FCL 4.0, if we were to write multithreaded programs, the task was obviously better than the traditional way.

The following is a simple example of a task:

Static voidMain (string[] args) {Task T=NewTask (() ={Console.WriteLine ("tasks begin to work ..."); //Simulation Work ProcessThread.Sleep ( the);      });      T.start (); T.continuewith (Task)={Console.WriteLine ("the task is completed and the status of the completion time is:"); Console.WriteLine ("iscanceled={0}\tiscompleted={1}\tisfaulted={2}", Task. IsCanceled, Task. IsCompleted, Task.          isfaulted);      });  Console.readkey (); } 

Task tasks have the following properties, which let us query the state of the task when it is completed:

IsCanceled was completed because of the cancellation.
IsCompleted completed successfully
Isfaulted completed because of an exception
It is important to note that the task does not provide a callback event to inform completion (like BackgroundWorker), which accomplishes a similar function by enabling a new task. The ContinueWith method can initiate a new task when a task is completed, which naturally supports the task's completion notification: We can get the result value of the original task in the new task.

Here is a slightly more complex example that supports the ability to complete notifications, cancel, get task return values, and more:

Static voidMain (string[] args) {CancellationTokenSource cts=NewCancellationTokenSource (); Task<int> t =Newtask<int> (() =Add (CTS. Token), CTS.      Token);      T.start ();      T.continuewith (taskended); //wait to press any key to cancel the taskConsole.readkey (); Cts.      Cancel ();  Console.readkey (); }   Static voidTaskended (task<int>Task) {Console.WriteLine ("the task is completed and the status of the completion time is:"); Console.WriteLine ("iscanceled={0}\tiscompleted={1}\tisfaulted={2}", Task. IsCanceled, Task. IsCompleted, Task.      isfaulted); Console.WriteLine ("The return value of the task is: {0}", Task.  Result); }   Static intAdd (CancellationToken CT) {Console.WriteLine ("Task begins ..."); intresult =0;  while(!Ct. iscancellationrequested) {result++; Thread.Sleep ( +); }      returnresult; } 


When you press the keyboard about 3 seconds after the start of the task, you get the following output:
Task begins ...
The task is completed and the status of the completion time is:
Iscanceled=false iscompleted=true Isfaulted=false
The return value of the task is: 3


You may be surprised that our task is handled by cancel, why the completed state iscanceled that column or false. Because in the work task, we deal with iscancellationrequested in business logic, but it is not handled by the Throwifcancellationrequested method. If you take the Throwifcancellationrequested method, the code should look like this:

Static voidMain (string[] args) {CancellationTokenSource cts=NewCancellationTokenSource (); Task<int> t =Newtask<int> (() =Addcanclebythrow (CTS. Token), CTS.      Token);      T.start ();      T.continuewith (Taskendedbycatch); //wait to press any key to cancel the taskConsole.readkey (); Cts.      Cancel ();  Console.readkey (); }   Static voidTaskendedbycatch (task<int>Task) {Console.WriteLine ("the task is completed and the status of the completion time is:"); Console.WriteLine ("iscanceled={0}\tiscompleted={1}\tisfaulted={2}", Task. IsCanceled, Task. IsCompleted, Task.      isfaulted); Try{Console.WriteLine ("The return value of the task is: {0}", Task.      Result); }      Catch(AggregateException e) {e.handle (err)= Err isoperationcanceledexception); }  }   Static intaddcanclebythrow (CancellationToken CT) {Console.WriteLine ("Task begins ..."); intresult =0;  while(true) {Ct.          Throwifcancellationrequested (); Result++; Thread.Sleep ( +); }      returnresult; } 

Then the output is:
Task begins ...
The task is completed and the status of the completion time is:
Iscanceled=true iscompleted=true Isfaulted=false


In the method Taskendedbycatch of the task end evaluation, if the task ends with the Throwifcancellation requested method, Finding the result value for a task throws an exception operationcanceledexception, not the result value before the exception is thrown. This means that the task is canceled by way of exception, so you can notice that the status iscanceled is true in the output of the above code.

Then look at the output above, and we notice that the cancellation is implemented in an unusual way, and that the isfaulted state of the exception in the task is still false. This is because throwifcancellation requested is a method in the type CancellationTokenSource of the cooperative cancellation method, which the CLR has handled specially. The CLR knows that this is a program that the developer is interested in, so it is not considered an exception (it is understood to be canceled). To get the state that isfaulted equals true, we can modify the while loop to simulate an exception, as follows:

 while (true)  {  //Ct. Throwifcancellationrequested ();   if 5   {      thrownew Exception ("error" ) );  }  Result+ +;  Thread.Sleep (+);  

The output after the simulated exception is:

Task begins ...
The task is completed and the status of the completion time is:
Iscanceled=false iscompleted=true Isfaulted=true


The task also supports the concept of a mission factory. The task factory supports the sharing of the same state between multiple tasks, such as canceling type CancellationTokenSource that can be shared. By using a task factory, you can cancel a set of tasks at the same time:

Static voidMain (string[] args) {CancellationTokenSource cts=NewCancellationTokenSource (); //wait to press any key to cancel the taskTaskFactory TaskFactory =NewTaskFactory (); Task[] Tasks=Newtask[] {taskfactory.startnew ()=Add (CTS. Token), Taskfactory.startnew (()=Add (CTS. Token), Taskfactory.startnew (()=Add (CTS.      Token)}; //Cancellationtoken.none indicates that tasksended cannot be canceledTaskfactory.continuewhenall (Tasks, tasksended, cancellationtoken.none);      Console.readkey (); Cts.      Cancel ();  Console.readkey (); }   Static voidtasksended (task[] tasks) {Console.WriteLine ("All tasks are complete! "); } 

The output of the above code is:

Task begins ...
Task begins ...
Task begins ...
All tasks have been completed (canceled)!


This recommendation shows how task (Task) and TaskFactory (Task Factory) are used. Task further optimizes the scheduling of the background thread pool and speeds up the processing of threads. So in the FCL 4.0 era, if you want to use multi-threading, we should use task more.

Therefore, in the next recommendations of this book, if it is not particularly necessary, as long as the multi-threaded content is involved, the task will be used together.

Turn from: 157 recommendations for writing high-quality code to improve C # programs Minjia

157 recommendations for writing high-quality code to improve C # programs--recommendation 80: Replace ThreadPool with Task

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.