Wednesday, October 05, 2011

Waiting for Parallel Tasks to Complete

Synchronisation

When you are developing software that uses the Task class to include parallel operations, you will often have situations where a task must be completed before the main thread can continue processing. This may be because the parallel task generates results that are needed later in the process and you must wait for the results to be available before you attempt to use them. The parallel tasks must therefore be synchronised for the correct operation of the software.

The Task Parallel Library (TPL) includes several methods that allow you to wait for one or more parallel tasks to complete before continuing processing. In this article we will examine three such methods. They are all members of the Task class, which resides in the System.Threading.Tasks namespace. We will also be using the Thread class from the System.Threading namespace in order to simulate long-running tasks. To follow the samples, create a new console application project and add the following using directives to the initial class.

using System.Threading;
using System.Threading.Tasks;

Task.Wait Method

Often you will wish to wait for a single task to complete, either successfully or with an exception, before continuing. This can be achieved with the Task class' Wait method. In the most basic situation this blocks the thread from which it is called until the task being waited for stops. Once the task completes or throws an exception, the primary thread restarts.

As discussed earlier in the tutorial, the scheduling of tasks by the TPL is quite sophisticated. This is the case with the Wait method. Although it can be assumed that the main thread is blocked whilst a parallel task finishes its work, this is not always the case. If there is enough processor capability available and the task being waited for has not yet started, the task may be transferred to the main thread for processing. This can be more efficient, as a thread does not need to be blocked, and can mean that the task is started sooner than expected.

To demonstrate the use of the Wait method, first consider the following sample code. Here we start a task that simulates retrieving some numeric data from an external data source. The task shows a message, pauses for five seconds and then returns an array of ten integers. The main thread uses the results of the task by summing them and outputting the result.

When you run the program you will see that it throws an ArgumentNullException. This is caused by trying to use the array before it has been populated by the parallel task.

int[] values = null;

Task loadDataTask = new Task(() =>
{
    Console.WriteLine("Loading data...");
    Thread.Sleep(5000);
    values = Enumerable.Range(1,10).ToArray();
});
loadDataTask.Start();

Console.WriteLine("Data total = {0}", values.Sum());    // ArgumentNullException


Read more: BlackWasp
QR: TaskWait.aspx

Posted via email from Jasper-Net