Click to Rate and Give Feedback
Collapse All/Expand All Collapse All
.NET Framework 4
Task Parallel Library Overview

[This documentation is for preview only, and is subject to change in later releases. Blank topics are included as placeholders.]

The Task Parallel Library (TPL) is a set of public types and APIs in the System.Threading and System.Threading.Tasks namespaces in the .NET Framework version 4. These types rely on a task scheduler that is integrated with the .NET ThreadPool. The purpose of the TPL is to make developers more productive by simplifying the process of adding parallelism and concurrency to applications.

The TPL scales the degree of concurrency dynamically to most efficiently use all the processors that are available. Parallel code that is based on the TPL not only works on dual-core and quad-core computers. It will also automatically scale, without recompilation, to manycore computers.

When you use the TPL, writing a multithreaded for loop closely resembles writing a sequential for loop. The following code automatically partitions the work into tasks, based on the number of processors on the computer.

Visual Basic
        Parallel.For(startIndex, endIndex, Sub(currentIndex) DoSomeWork(currentIndex))

C#
Parallel.For(startIndex, endIndex, (currentIndex) => DoSomeWork(currentIndex));

By using ParallelInvoke()()(), you can invoke any number of asynchronous, concurrent operations by using just one method call, as follows.

Visual Basic
Parallel.Invoke(
    Sub() MethodA(),
    Sub() MethodB(),
    Sub() MethodC())
C#
Parallel.Invoke(
            () => MethodA(),
            () => MethodB(),
            () => MethodC());

By using TPL to parallelize your code, you can focus on the work that your program is designed to accomplish. However, not all sequential loops are good candidates for parallelization. Parallel loops, like any multithreaded code, can introduce complexity into your program execution. Although the TPL simplifies multithreaded scenarios, we recommend that you have a basic understanding of threading concepts, for example, locks, deadlocks, and race conditions, so that you can use the TPL effectively.

In the TPL, the basic abstraction is the Task, not the thread. A task is an instance of the Task class. A task can be canceled and waited on, can return a value, and can invoke another task when it completes. When you use Parallel.For and Parallel.ForEach, even the Task object itself is implicit. In your code, you just supply the delegate that performs the desired work. The TPL handles the rest. By default, the TPL uses its own task scheduler, which is integrated with the .NET ThreadPool. However, you can also provide a custom task scheduler that uses some other thread-scheduling mechanism. There is no fixed relationship between a task and a thread. A thread may run several tasks in succession for any given block of parallel code. A task may define a child task that runs on the same thread, or a different thread. A task may also invoke another task that has been defined elsewhere.

You can also access parallel functionality in declarative syntax by using Parallel LINQ (PLINQ). Internally, PLINQ is closely integrated with the Task Parallel Library. For more information, see Parallel LINQ (PLINQ).

One common programming pattern is to use a loop to perform the same action or set of actions against each element in a data source. In data parallel operations, the source collection is partitioned so that multiple threads can operate on different segments concurrently. TPL supports data parallelism through the System.Threading.Tasks..::.Parallel class. This class provides method-based parallel implementations of for and foreach loops (For and For Each in Visual Basic). You write the loop logic for a ParallelFor()()() or ParallelForEach()()() loop much as you would write a sequential loop. You do not have to create threads or queue work items. In basic loops, you do not have to take locks. The TPL handles all the low-level work for you. The following code example shows a simple foreach loop and its parallel equivalent.

Visual Basic
' Sequential version        
For Each item In sourceCollection
    Process(item)
Next

' Parallel equivalent
Parallel.ForEach(sourceCollection, Sub(item) Process(item))
C#
// Sequential version            
foreach (var item in sourceCollection)
{
    Process(item);
}

// Parallel equivalent
Parallel.ForEach(sourceCollection, item => Process(item));

When a parallel loop runs, the TPL partitions the data source so that the loop can operate on multiple parts concurrently. Behind the scenes, the Task Scheduler partitions the task based on system resources and workload. When possible, the scheduler redistributes work among multiple threads and processors if the workload becomes unbalanced.

NoteNote

You can also supply your own custom partitioner or scheduler.

Both the ParallelFor()()() and ParallelForEach()()() methods have several overloads that let you stop or break loop execution, monitor the state of the loop on other threads, maintain thread-local state, finalize thread-local objects, control the degree of concurrency, and so on. The helper types that enable this functionality include ParallelLoopState, ParallelOptions, and ParallelLoopResult, CancellationToken and CancellationTokenSource.

For more information, see Data Parallelism (Task Parallel Library).

In task parallelism, multiple distinct operations are performed concurrently on the same or different sources. For example, one might search a chunk of text for the most frequently occurring word, while at the same time search for the longest word and also analyze the content by using a proprietary algorithm. In traditional .NET Framework applications, you perform this concurrent work by using the ThreadPool or by explicitly creating and starting threads. With the TPL, think in terms of tasks, not threads.

The ParallelInvoke()()() method provides a convenient way to run any number of arbitrary statements concurrently. Just pass in an Action delegate for each item of work. The easiest way to create these delegates is to use lambda expressions. The lambda expression can either call a named method, or provide the code inline. The following example shows a basic Invoke()()() call that creates and starts two tasks that run concurrently.

Visual Basic
Parallel.Invoke(Sub() DoSomeWork(), Sub() DoSomeOtherWork())
C#
Parallel.Invoke(() => DoSomeWork(), () => DoSomeOtherWork());
NoteNote

The number of tasks that are created behind the scenes by Parallel.Invoke is not necessarily equal to the number of delegates that are provided. TPL may employ various optimizations, especially with large numbers of delegates.

For more information, see How to: Use Parallel.Invoke to Execute Parallel Operations.

For greater control over task execution, for example, canceling, waiting on, and continuing from a task, you have to work with task objects more explicitly.

© 2009 Microsoft Corporation. All rights reserved. Terms of Use | Trademarks | Privacy Statement | Site Feedback
Page view tracker