Using Classic Sleep

Because the TPL uses the classic .NET threading support behind the scenes, you can use the classic threading technique to put a Task to sleep. Call the static Thread.Sleep() method, and pass a time interval as an argument. Listing 2-14 reworks the previous example to use this technique. Listing 2-14. Sleeping Using Classic Threads create the cancellation token source CancellationTokenSource tokenSource new CancellationTokenSource() create the cancellation token CancellationToken token...

Determining If a Task Was Cancelled

You can determine if a Task has been cancelled by checking the IsCancelled property, which will return true if the Task was cancelled. Listing 2-12 demonstrates the use of this property. Listing2-12. Using the Task.isCancelled Property 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 gt...

Common Parallel Algorithms

In this chapter are 11 common parallel algorithms implemented using the TPL. You can download all of the source code for all of the algorithms from www.Apress.com. These are some of the most widely used building blocks in parallel programming, and I have included them as a reference for when you are facing a problem, a time-saver for when you need a quick answer, and a demonstration of how the TPL abstractions we covered throughout this book allow complex and rich functions to be developed with...

Using the Reader WriterLock Slim Class

The System.Threading.ReaderWriterLockSlim class provides a convenient implementation of reader-writer locking that takes care of managing the locks. This class is a lightweight alternative for the heavyweight System.Threading.ReaderWriter, which Microsoft no longer recommends using. The lightweight version is simpler to use, offers better performance, and avoids some potential deadlocks. You acquire and release the ReaderWriterLockSlim read lock by calling the EnterReadLock and ExitReadLock...

Writing a Contextual Partitioner

The default partitioner and the chunking partitioner both operate on any data type. One advantage of writing a customer partitioner is that you can tailor your strategy to the data type that you need to process. This section will demonstrate how to implement a contextual partitioner and, in doing so, explain how to extend the Partitioner class to implement a custom technique. To start our partitioner, we need a context some data type with characteristics that we are going to specialize. I have...

Creating Manyto One and AnyToOne Continuations

The continuations we have seen so far have been one-to-one or one-to-many that is, one antecedent has one or more continuations. You can also perform many-to-one continuations using the ContinueWhenAll and ContinueWhenAny methods of the System.Threading.Tasks.TaskFactory class. You obtain an instance of TaskFactory through the static Task.Factory property. The ContinueWhenAll and ContinueWhenAny methods both take an array of Tasks argument. ContinueWhenAll schedules a continuation to be...

Member Description

QueueTask This method is called by the TPL when a Task has been created and TryExecuteTask This one is called by the scheduler to synchronously execute a Task that has been previously passed to the scheduler via the QueueTask method. The Task will not be executed if it is already executing or has already been executed. It returns true if the task was executed. TryExecuteTaskInLine This is called by the TPL to request that a Task be executed inline, and returns true if your scheduler executes...

Canceling Continuations

The techniques to handle cancellations for single Tasks, which we covered in the previous chapter, can be applied to continuations. The Task.ContinueWith , TaskFactory.ContinueWhenAll , and TaskFactory.ContinueWhenAny methods all have overloaded versions that accept a CancellationToken, which you can obtain by creating an instance of CancellationTokenSource. Listing 4-7 demonstrates canceling continuations. An antecedent Task is created and waits using a CancellationToken wait handle. When the...

Debugging Program State

The best approach is to use the Visual Studio debugger, which contains some very useful new parallel features to support parallel programming. To look at these features, we are going to use the code in Listing 7-4. This program has no useful value other than it causes a number of Tasks to call a number of methods to demonstrate the debugger features. The CountDownEvent is used so that the main application thread can wait until all of the Tasks have been created and scheduled. The SemaphoreSlims...

Using Spin Waiting

The spin waiting technique is included in this chapter for completeness, but I recommend against using it. When you use the other two sleep techniques, the thread that is performing your task gives up its turn in the schedule when its sleeping, so any other threads can have a turn. The scheduler, which is responsible for managing the threads running at any given time, has to do some work to determine which thread should go next and make it happen. You can avoid the scheduler having to do this...

Creating Selective Continuations

By default, continuation Tasks are automatically scheduled when the antecedent Task completes. We can be selective about scheduling continuations by using the values of the enumeration when calling the Task.ContinueWith method. Table 4-2 details the enumeration values. Table 4-2. Key Values of the Enumeration Table 4-2. Key Values of the Enumeration This is equivalent to not specifying a value that is, the continuation will be scheduled to run when the antecedent completes. The continuation...

Setting Parallel Loop Options

You can influence the behavior of parallel loops by supplying an instance of the ParallelOptions class as an argument to Parallel.For or Parallel.ForEach . There are three properties in ParallelOptions, and they are described in Table 5-2. Table 5-2. Properties of the System.Threading.Tasks.ParallelOptions class Table 5-2. Properties of the System.Threading.Tasks.ParallelOptions class Get or set a CancellationToken see the Canceling Parallel Loops section Get or set the maximum concurrency for...

Concurrent Dictionary

The ConcurrentDictionary class implements a collection of key-value pairs. Like the other collection classes in the System.Collections.Concurrent namespace, ConcurrentDictionary provides methods whose names are prefixed with Try and returns bool results if they operate successfully. Table 3-9 describes the key members of the ConcurrentDictionary class. Table3-9. Key members of Try to add a new key-value pair to the collection. Return true if the pair was added successfully. Try to get the value...

Using Recursion and Upgradable Read Locks

Listing 3-15 separates the code that reads the shared data from the code that modifies it. Often, you will want to read data and make a change only if some condition is met. You could acquire the write lock to do this, but that requires exclusive access. Because you don't know in advance if you actually need to make changes, that would be a potential performance problem. But you are thinking, Aha I can acquire the nonexclusive read lock, perform the test, and then acquire the exclusive write...

Creating Child Tasks

A child Task, sometimes known as a nested Task, is one that is created inside the Task body of another. The Task in which the child is created is known as the parent. There are two kinds of child Task detached and attached. A detached Task, as demonstrated in Listing 4-10, has no special relationship with its parent the child will be scheduled and can be performed concurrently with the parent but has no impact on the parent itself. Create a new Task within the body of an existing one. Create a...

Performing Parallel Analysis with Visual Studio

Visual Studio 2010 includes the Concurrency Visualizer, which allows you to examine the behavior of your parallel program, albeit it with some significant limitations and frustrations. To use the Concurrency Visualizer, Visual Studio must be started with Administrator privileges. To do this, find Visual Studio in your Start menu, right-click it, and select Run as administrator. Load your project, and select Start Performance Analysis from the Debug menu. Note If you are running Windows 64-bit,...

Creating a Composite Cancellation Token

You can create a token that is composed from several CancellationTokens that will be cancelled if any of the underlying tokens is cancelled. You do this by calling the System.Threading. method and passing in the CancellationTokens that you want to link. The result is a new CancellationToken that you can use normally. Listing 2-11 demonstrates creating and using a composite cancellation token. Listing 2-11. Using a Composite Cancellation Token create the cancellation token sources...