stackdane
stackdane

Reputation: 21

C# - Parallel.ForEach loop wont stop after nested while loop was stopped

I'm currently running a Parallel.ForEach loop which contains a while loop.

Those will be run untill a condition cancels them. As you will see the while loop is only running until a valid response sets the userChanged bool to true.

My problem:

The loopState.Break(); code doesn't seem to stop the Parallel.ForEach loop. What am I doing wrong?

After the userChanged bool is set to true, the function will jump back to the following line:

Parallel.ForEach(dataGridView1.Rows.Cast<DataGridViewRow>(), (row, loopState) =>

and restart the code. I aprreciate any kind of suggestions and help!

Example code:

private void function()
{
    Parallel.ForEach(dataGridView1.Rows.Cast<DataGridViewRow>(), (row, loopState) =>
    {
        try
        {
            // HttpWebRequest

            bool userChanged = false;

            while (!userChanged)
            {
                try
                {
                    WebClient client1 = new WebClient
                    {
                        Proxy = null
                    };

                    client1.Headers["Accept-Language"] = "en-us";

                    if (client1.DownloadString("https://url.com/" + row.Cells[0].Value.ToString()).Contains("Sorry, that page doesn’t exist!"))
                    {
                        if (!userChanged)
                        {
                            // Request

                            if ( /* condition is true */ )
                            {
                                MessageBox.Show("Success", "Info", MessageBoxButtons.OK);
                                userChanged = true;

                                requestStream.Close();

                                loopState.Break();
                            }
                        }
                    }
                    else
                    {
                        // Call another function
                    }
                }
                catch (WebException ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }

    });
}

Upvotes: 0

Views: 547

Answers (2)

Henk Holterman
Henk Holterman

Reputation: 273179

Yes, cancellation has to be cooperative.

while (!userChanged && !loopState.ShouldExitCurrentIteration)

I think you can even do without userChanged which is only the local state. ShouldExitCurrentIteration is shared between this iteration and all others.

Upvotes: 1

WueF
WueF

Reputation: 460

Try using loopState.Stop()

According to docs:

Calling the Break method informs the for operation that iterations after the current one don't have to execute. However, all iterations before the current one will still have to be executed if they haven't already. and there is no guarantee that iterations after the current one will definitely not execute.

MSDN

Upvotes: 2

Related Questions