FPGA
FPGA

Reputation: 3855

Pausing and resuming a Parallel.ForEach

    private bool isProcessing=false;
    public bool IsProcessing { get { return isProcessing; } }

    private bool IsTerminated=false;

    private bool isPaused=false;
    public bool IsPaused { get { return isPaused; } }

and this function which contains the Parallel.ForEach

private void StartProcess()
        {
            isPaused = IsTerminated = false;
            isProcessing = true;

            Parallel.ForEach(items, new ParallelOptions() { MaxDegreeOfParallelism = 4 }, (item, state) =>
                {
                    if (isPaused) state.Stop();
                    if (IsTerminated) state.Break();
                    item.Process();
                });

            isPaused = IsTerminated = false;
            isProcessing = false;
        }

consider the following, the StartProcess() got called, then IsTerminated got set to true the loop breaks and same happens when isPaused set to true, i am not sure how i could resume the Parallel.ForEach after Stop() is called, how could i get the index of where each thread has started and stopped?

in the case of pause/resume i did it by adding a boolean value to the item object to indicate if it was processed, and then on resume calling StartProcess() again and skipping the items that were processed, but i am sure there is a better way , a way in which i don't need to customize my object structure, another way is adding the processed items references to a list and skipping them on resume

Upvotes: 2

Views: 3898

Answers (2)

Scott Chamberlain
Scott Chamberlain

Reputation: 127543

You need to get the ParallelLoopResult back from the Parallel.ForEach call. It will tell you which was the last element processed.

Also you appear to have Stop() and Break() backwards. Stop() stops as soon as possible, some items below the last item you have processed may not have been processed yet. Break() stops as soon as possible, but it continues processing until all items that came before the current item has been processed, it then reports the index of the last processed item.

   private long? lowestBreakIndex = null;

    private void StartProcess()
    {
        isPaused = IsTerminated = false;
        isProcessing = true;

        ParallelLoopResult result = Parallel.ForEach(
            items.Skip(lowestBreakIndex ?? 0) //I am assuming that items is some form of ICollection. The Skip function will skip to the next item to process
            , new ParallelOptions() { MaxDegreeOfParallelism = 4 }, (item, state) =>
            {
                //I swapped these two.
                if (isPaused) 
                    state.Break();
                else if (IsTerminated) 
                    state.Stop();
                else
                    item.Process();
            });

        lowestBreakIndex = result.LowestBreakIteration;

        isPaused = IsTerminated = false;
        isProcessing = false;
    }

Important note: You could potentially run the same item twice. Note the name of the propterty is LowestBreakItteration, if two threads both report the break the lower of the two will be the one who reports it's result.

For more information about Stop() and Break() see this old answer of mine from another question about Parallel.ForEach.

Upvotes: 3

Tono Nam
Tono Nam

Reputation: 36048

seems that u need

http://msdn.microsoft.com/en-us/library/dd267312(v=vs.110).aspx

create 4 threads if the computer has 4 cores.

Upvotes: 1

Related Questions