Free mag vol1 | Page 789

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