CHAPTER 19 MULTITHREADED, PARALLEL, AND ASYNC PROGRAMMING
While you could call the Parallel.For() and Parallel.ForEach() methods and pass a strongly typed
Func or Action delegate object, you can simplify your programming by making use of a fitting C#
anonymous method or lambda expression.
Data Parallelism with the Parallel Class
The first way to use the TPL is to perform data parallelism. Simply put, this term refers to the task of
iterating over an array or collection in a parallel manner using the Parallel.For() or Parallel.ForEach()
methods. Assume you need to perform some labor-intensive file I/O operations. Specifically, you need
to load a large number of *.jpg files into memory, flip them upside down, and save the modified image
data to a new location.
The .NET Framework 4.5 SDK documentation provides a console-based example of this very
situation; however, we will perform the same overall task using a graphical user interface, in order to
examine the use of “anonymous delegates” to allow secondary threads to update the primary user
interface thread (a.k.a. the UI thread).
Note When you are building a multithreaded graphical user interface (GUI) application, secondary threads can
never directly access user interface controls. The reason is that controls (buttons, text boxes, labels, progress
bars, etc.) have thread affinity with the thread that created them. In the following example, I’ll illustrate one way to
allow secondary threads to access UI items in a thread-safe manner. You’ll see a more simplified approach when
we examine the .NET 4.5 C# async and await keywords.
To illustrate, create a Windows Forms application named DataParallelismWithForEach, and use the
Solution Explorer to rename the Form1.cs to MainForm.cs. After you do so, import the following
namespaces in your primary code file:
// Be
using
using
using
sure you have these namespaces!
System.Threading.Tasks;
System.Threading;
System.IO;
The GUI of the application consists of a multiline TextBox and a single Button (named
btnProcessImages). The purpose of the text area is to allow you to enter data while the work is being
performed in the background, thus illustrating the nonblocking nature of the parallel task. The Click
event of this Button will eventually make use of the TPL, but for now, author the following blocking code.
Note You should update the string passed into the following Directory.GetFiles() method call to point to a
path on your computer that has some image files (such as a personal folder of family pictures). Here, I am just
pointing to some sample pictures stored under C:\Users\Public\Pictures\Sample Pictures.
733