Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Daniel Solis - Illustrated C# 2010 - 2010.pdf
Скачиваний:
16
Добавлен:
11.06.2015
Размер:
11.23 Mб
Скачать

CHAPTER 22 INTRODUCTION TO ASYNCHRONOUS PROGRAMMING

Parallel Loops

.NET 4.0 has introduced a new library, called the Task Parallel Library, which greatly simplifies parallel programming. This is a huge advance and includes a large amount of material—far more than I can cover in this chapter. So unfortunately, I’ve had to settle by just whetting your appetite by introducing just two of its very simple constructs that you can learn and use quickly and easily. These are the Parallel.For loop and the Parallel.ForEach loop. These constructs are in the

System.Threading.Tasks namespace.

By this point in the book I’m sure you’re quite familiar with C#’s standard for and foreach loops. These are common and tremendously powerful constructs. Many times when using these constructs, each iteration depends on a calculation or action in the previous iteration. But this isn’t always the case. When the iterations are independent, it would be a huge advantage if you could put different iterations on different processors and process them in parallel. This is exactly what the Parallel.For and

Parallel.ForEach constructs do.

These constructs are in the form of methods with input parameters. There are 12 overloads of the Parallel.For method, but the simplest has the following signature:

The fromInclusive parameter is the first integer in the iteration series.

The toExclusive parameter is an integer that is one greater than the last index in the iteration series. That is, it’s the same as comparing on the expression index < ToExclusive.

The body is a delegate that takes a single input parameter. The code of body is executed once per iteration.

void Parallel.For( int fromInclusive, int toExclusive, Action body );

The following code is an example using the Parallel.For construct. It iterates from 0 to 15 and prints out the iteration index and the square of the index. Notice that it fits the requirement that each iteration is independent of any other iteration. Notice also that you must use the

System.Threading.Tasks namespace.

using

System;

 

using

System.Threading.Tasks;

// Must use this namespace

namespace ExampleParallelFor

{

class Program

{

static void Main( )

{

Parallel.For( 0, 15, i =>

Console.WriteLine( "The square of {0} is {1}", i, i * i ));

}

}

}

599

CHAPTER 22 INTRODUCTION TO ASYNCHRONOUS PROGRAMMING

One run of this code on a PC with a two-core processor produced the following output. Notice that you’re not guaranteed any particular order of the iterations.

The square of 0 is 0

The square of 7 is 49

The square of 8 is 64

The square of 9 is 81

The square of 10 is 100

The square of 11 is 121

The square of 12 is 144

The square of 13 is 169

The square of 3 is 9

The square of 4 is 16

The square of 5 is 25

The square of 6 is 36

The square of 14 is 196

The square of 1 is 1

The square of 2 is 4

Another example is the following code. This program fills an integer array, in parallel, with the square of the iteration index.

class Program

{

static void Main()

{

const int maxValues = 50;

int[] squares = new int[maxValues];

Parallel.For( 0, maxValues, i => squares[i] = i * i );

}

}

Unlike the previous example, even though the iterations might be executed in parallel and in any order, the end result is an array containing the first 50 squares.

600

CHAPTER 22 INTRODUCTION TO ASYNCHRONOUS PROGRAMMING

The other parallel loop construct is the Parallel.ForEach method. There are more than a dozen overloads for this method, but the simplest is the following:

The TSource is the type of object in the collection.

The source is the collection of TSource objects.

The body is the lambda expression to be applied to each element of the collection.

static ParallelLoopResult ForEach<TSource>( IEnumerable<TSource> source, Action<TSource> body)

An example of using the Parallel.ForEach method is the following code. In this case, TSource is string, and the source is a string[].

using System;

using System.Threading.Tasks;

namespace ParallelForeach1

{

class Program

{

static void Main()

{

string[] squares = new string[]

{"We", "hold", "these", "truths", "to", "be", "self-evident", "that", "all", "men", "are", "created", "equal"};

Parallel.ForEach( squares,

i => Console.WriteLine( string.Format("{0} has {1} letters", i, i.Length) ));

}

}

}

One run of this code on a PC with a two-core processor produced the following output, but the order might change each time:

"We" has 2 letters "equal" has 5 letters "truths" has 6 letters "to" has 2 letters "be" has 2 letters "that" has 4 letters "hold" has 4 letters "these" has 5 letters "all" has 3 letters "men" has 3 letters "are" has 3 letters

"created" has 7 letters "self-evident" has 12 letters

601

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]