Free mag vol1 | Page 792

CHAPTER 19  MULTITHREADED, PARALLEL, AND ASYNC PROGRAMMING and Parallel.ForEach() methods both support cancellation through the use of cancellation tokens. When you invoke methods on Parallel, you can pass in a ParallelOptions object, which in turn contains a CancellationTokenSource object. First, define the following new private member variable in your Form derived class of type CancellationTokenSource named cancelToken: public partial class MainForm : Form { // New Form-level variable. private CancellationTokenSource cancelToken = new CancellationTokenSource(); ... } Now, assuming you have added a new Button (named btnCancel) on your designer, handle the Click event, and implement the handler as so: private void btnCancel_Click(object sender, EventArgs e) { // This will be used to tell all the worker threads to stop! cancelToken.Cancel(); } Now, the real modifications need to occur within the ProcessFiles() method. Consider the final implementation: private void ProcessFiles() { // Use ParallelOptions instance to store the CancellationToken. ParallelOptions parOpts = new ParallelOptions(); parOpts.CancellationToken = cancelToken.Token; parOpts.MaxDegreeOfParallelism = System.Environment.ProcessorCount; // 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); try { // Process the image data in a parallel manner! Parallel.ForEach(files, parOpts, currentFile => { parOpts.CancellationToken.ThrowIfCancellationRequested(); string filename = Path.GetFileName(currentFile); using (Bitmap bitmap = new Bitmap(currentFile)) { bitmap.RotateFlip(RotateFlipType.Rotate180FlipNone); bitmap.Save(Path.Combine(newDir, filename)); 737