CHAPTER 19 MULTITHREADED, PARALLEL, AND ASYNC PROGRAMMING
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
private void btnProcessImages_Click(object sender, EventArgs e)
{
ProcessFiles();
}
private void ProcessFiles()
{
// Load up all *.jpg files, and make a new folder for the modified data.
string[] files = Directory.GetFiles
(@"C:\Users\Public\Pictures\Sample Pictures", "*.jpg",
SearchOption.AllDirectories);
string newDir = @"C:\ModifiedPictures";
Directory.CreateDirectory(newDir);
// Process the image data in a blocking manner.
foreach (string currentFile in files)
{
string filename = Path.GetFileName(currentFile);
using (Bitmap bitmap = new Bitmap(currentFile))
{
bitmap.RotateFlip(RotateFlipType.Rotate180FlipNone);
bitmap.Save(Path.Combine(newDir, filename));
}
}
}
// Print out the ID of the thread processing the current image.
this.Text = string.Format("Processing {0} on thread {1}", filename,
Thread.CurrentThread.ManagedThreadId);
}
Notice that the ProcessFiles() method will rotate each *.jpg file under the specified directory,
which currently contains a total of 37 files (again, be sure to update the path sent into
Directory.GetFiles() as necessary). Currently, all of the work is happening on the primary thread of the
executable. Therefore, if the button is clicked, the program will appear to hang. Furthermore, the
caption of the window will also report that the same primary thread is processing the file, as we only
have a single thread of execution.
To process the files on as many CPUs as possible, you can rewrite the current foreach loop to make
use of Parallel.ForEach(). Recall that this method has been overloaded numerous times; however, in
the simplest form, you must specify the IEnumerable-compatible object that contains the items to
process (that would be the files string array) and an Action delegate that points to the method that
will perform the work.
734