}); // print the Task status Console.WriteLine("Task status: {0}", myTask.Status); // start the Task myTask.Start(); // print the Task status Console.WriteLine("Task status: {0}", myTask.Status); // wait for the Task to complete myTask.Wait(); // print the Task status Console.WriteLine("Task status: {0}", myTask.Status); // print out the result from the Task Console.WriteLine("Result: {0}", myTask.Result); // wait for input before exiting Console.WriteLine("Press enter to finish"); Console.ReadLine(); } } Listing 24-10 creates a Task<long> and prints out the value of the Status property as the Task goes through its life. Compiling and running Listing 24-10 produces the following results: Task status: Created Task status: Running Task status: RanToCompletion Result: 2305843005992468481 Press enter to finish These results show the Task moving from the Created status to Running and finally to RanToCompletion. When you run this example, you might see slightly different results, like this: Task status: Created Task status: WaitingToRun Task status: RanToCompletion Result: 2305843005992468481 Press enter to finish You can see the WaitingToRun status if the TPL has not started execution of your Task before the Status property is read.

Using Barcode drawer for Java Control to generate, create Data Matrix ECC200 image in Java applications.

www.OnBarcode.com

Returns true if the Task has been cancelled (see the Cancelling Tasks section later in this chapter). Returns true if the Task has competed. Returns true if the Task has encountered an exception ( see the Handling Task Exceptions section later in this chapter for more details).

Using Barcode recognizer for Software Control to read, scan read, scan image in Software applications.

www.OnBarcode.com

The IsCompleted property will return true if the Task has completed, even if the reason for its completion is because the Task was cancelled or because it encountered an Exception. See the relevant sections later in this chapter for details of cancelling Tasks and handling exceptions in Tasks.

Canceling Tasks

Occasionally, you will want to stop a Task without waiting for it to complete its work; for example, in response to the user clicking a Cancel button. The TPL has a mechanism for supporting Task cancellation using a technique called cooperative cancelation meaning that your Task body has to be written so that it checks to see if the Task has been cancelled. Listing 24-11 shows how to cancel a Task. Listing 24-11. Canceling a Task using System; using System.Threading; using System.Threading.Tasks; class Listing 11 { static void Main(string[] args) { // create a token source CancellationTokenSource cancelTS = new CancellationTokenSource(); // create and start a Task using the Token Task myTask = Task.Factory.StartNew(() => { long total = 0; // do some work

CHAPTER 24 PARALLEL PROGRAMMING

Console.WriteLine("Doing first chunk of work..."); for (int i = 0; i < int.MaxValue; i++) { total += i; } // check to see if we have been canceled if (cancelTS.Token.IsCancellationRequested) { Console.WriteLine("Cancellation detected"); // we can perform any tidying up here - closing streams, etc // throw an exception to show that we have canceled properly throw new OperationCanceledException(cancelTS.Token); } // do some more work Console.WriteLine("Doing second chunk of work..."); for (int i = 0; i > int.MinValue; i--) { total += i; } // print out the total Console.WriteLine("Total: {0}", total); }, cancelTS.Token); // read a line from the Console Console.WriteLine("Press enter to cancel token"); Console.ReadLine(); // cancel the token Console.WriteLine("Token canceled"); cancelTS.Cancel(); // wait for input before exiting Console.WriteLine("Press enter to finish"); Console.ReadLine(); } } The first step in creating a cancelable Task is to create an instance of the CancellationTokenSource class which can be found in the System.Threading namespace. The Token property of this class returns a CancellationToken object that can be used by the TPL and the Task body to monitor for cancellation. The second step is to create a Task object using the result of the CancellationToken.Token property as a constructor argument. Listing 24-11 uses the StartNew method to create and start the Task in a single statement; the first parameter is the lambda expression containing the Task body, and the second parameter is the result of the Token property. The Task body has to cooperate with the cancellation, which it does by checking the IsCancellationRequested property of the CancellationToken obtained through the Token property of the CancellationToken source, like this: