Cancelling a parallel foreach loop

When dealing with parallel foreach loops, the obvious question is how one would terminate the loop prematurely based on a certain condition, such as a timeout. As it turns out, the parallel foreach loop is quite easy to terminate prematurely.

Getting ready

We will create a method that takes a collection of items and loops through this collection in a parallel foreach loop. It will also be aware of a timeout value that, if exceeded, will terminate the loop and exit the method.

How to do it…

  1. Start off by creating a new method called CancelParallelForEach() in the Recipes class, which takes two parameters. One is a collection of List<string>, while the other is an integer specifying a timeout value. When the timeout value is exceeded, the Parallel.ForEach loop must terminate:
    public class Recipes
    {
        public void CancelParallelForEach(List<string> intCollection, int timeOut)
        {        
    
        }    
    }
  2. Inside the CancelParallelForEach() method, add a timer to keep track of the elapsed time. This will signal the loop that the timeout threshold has been exceeded and that the loop needs to exit. Create the Parallel.ForEach method, defining a state. In each iteration, check the elapsed time against the timeout, and if the time is exceeded, break out of the loop:
    var timer = Stopwatch.StartNew();
    Parallel.ForEach(intCollection, (integer, state) =>
    {
        Thread.Sleep(1000);
        if (timer.Elapsed.Seconds > timeOut)
        {
            WriteLine($"Terminate thread {Thread.CurrentThread.ManagedThreadId}.Elapsed time {timer.Elapsed.Seconds} seconds");
            state.Break();
        }
        WriteLine($"Processing item {integer} on thread {Thread.CurrentThread.ManagedThreadId}");
    });
  3. In the console application, create the List<string> object and add 1000 items to it. Call the CancelParallelForEach() method with a timeout of only 5 seconds:
    List<string> integerList = new List<string>();
    for (int i = 0; i <= 1000; i++)
    {
        integerList.Add(i.ToString());
    }
    
    Chapter7.Recipes oRecipe = new Chapter7.Recipes();
    oRecipe.CancelParallelForEach(integerList, 5);
    WriteLine($"Parallel.ForEach loop terminated");
    ReadLine();
  4. Run your console application and review the output results:
    How to do it…

How it works…

You can see from the console window output that as soon as the elapsed time exceeded the timeout value, the parallel loop was notified to cease the execution of iterations beyond the current iteration at the system's earliest convenience. Having this kind of control over the Parallel.ForEach loop allows developers to avoid runaway loops and give the user control to cancel a loop operation by clicking on a button, or automatically having the application terminate when the timeout value has been reached.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.123.147