Free mag vol1 | Page 790

CHAPTER 19  MULTITHREADED, PARALLEL, AND ASYNC PROGRAMMING Here is the relevant update, using the C# lambda operator in place of a literal Action delegate object. Notice that we are currently commenting out the line of code that displayed the ID of the thread executing the current image file. See the next section to find out the reason why. // Process the image data in a parallel manner! Parallel.ForEach(files, currentFile => { string filename = Path.GetFileName(currentFile); using (Bitmap bitmap = new Bitmap(currentFile)) { bitmap.RotateFlip(RotateFlipType.Rotate180FlipNone); bitmap.Save(Path.Combine(newDir, filename)); } // This code statement is now a problem! See next section. // this.Text = string.Format("Processing {0} on thread {1}", filename, // Thread.CurrentThread.ManagedThreadId); } ); Accessing UI Elements on Secondary Threads You’ll notice that I’ve commented out the previous line of code that updated the caption of the main window with the ID of the currently executing thread. As noted previously, GUI controls have “thread affinity” with the thread that created it. Y