0
votes

I'm not sure exactly where the problem lies here, i think from searching it's in the "Parallel.ForEach" which is throwing the error, on a couple of systems the program runs fine but on my VPS the application crashes a few seconds in everytime.

    private void bgWorkerCheckURLs_DoWork(object sender, DoWorkEventArgs e)
    {
        try
        {
            string action = e.Argument.ToString();
            if (action == "wraith_check_links")
            {
                int unidentified = 1;
                int identified = 1;

                Parallel.ForEach(dgView.Rows.Cast<DataGridViewRow>(), (DataGridViewRow dataGridViewRow, ParallelLoopState parallelLoopState) =>
                {
                    var backgroundWorker = sender as BackgroundWorker;
                    if (backgroundWorker.CancellationPending)
                    {
                        e.Cancel = true;
                        parallelLoopState.Break();
                        toolStripStatusLabel.Text = "Cancelling...";
                    }
                    else
                    {
                        List<string> urls;
                        string url = dataGridViewRow.Cells["url"].Value.ToString();
                        UrlRow urlRow = CheckUrl(url);
                        string platform = urlRow.Platform;
                        Invoke((Action)(() =>
                        {
                            dataGridViewRow.Cells["platform"].Value = platform;
                            dataGridViewRow.DefaultCellStyle.BackColor = urlRow.BackColor;
                            dataGridViewRow.DefaultCellStyle.ForeColor = urlRow.ForeColor;
                            if (platform == "UNIDENTIFIED")
                            {
                                lblPlatformsUnIdentified.Text = unidentified.ToString();
                                Interlocked.Increment(ref unidentified);
                            }
                            else
                            {
                                lblPlatformsIdentified.Text = identified.ToString();
                                Interlocked.Increment(ref identified);
                            }
                        }));
                        if (platforms.ContainsKey(platform))
                        {
                            urls = platforms[platform];
                        }
                        else
                        {
                            urls = new List<string>();
                        }
                        urls.Add(url);
                        platforms[platform] = urls;
                    }
                });
            }
        }
        catch (Exception ex)
        {
            Helpers.returnMessage(ex.Message);
        }
    }

The technical details are:

Problem signature:

Problem Event Name: CLR20r3

Problem Signature 01: wraithplatformidentifier.exe

Problem Signature 02: 1.0.0.1

Problem Signature 03: 563f8d36

Problem Signature 04: System

Problem Signature 05: 4.0.30319.17929

Problem Signature 06: 4ffa5c88

Problem Signature 07: 23f8

Problem Signature 08: 59

Problem Signature 09: System.AggregateException

OS Version: 6.1.7601.2.1.0.274.10

Locale ID: 1033

Additional Information 1: 0a9e

Additional Information 2: 0a9e372d3b4ad19135b953a78882e789

Additional Information 3: 0a9e

Additional Information 4: 0a9e372d3b4ad19135b953a78882e789

It only crashes on the VPS but it could possibly be on more systems if i left the error.

Can anyone see what i'm doing wrong?

thanks guys

Graham

1
It looks like it probably is thrown by the Parallel.Foreach code, but as you are only logging the exception message, not the stack trace, it's very hard to pinpoint exactly where the actual problem is. - Rhumborl
@Rhumborl But he catches that exception and not throwing it forward - that should not happen. - shay__
@graham23s, If the code runs single threaded (simple foreach instead of Parallel.ForEach), would the app still crash? - shay__

1 Answers

0
votes

I see at least 3 potential places where the threading is not safe.

lblPlatformsUnIdentified.Text = unidentified.ToString();
lblPlatformsIdentified.Text = identified.ToString();

These controls could be being changed by different threads at the same time.

platforms[platform] = urls;

It looks like platforms is global list. It is possible multiple threads could be trying to update the same index.

To quickly test this, create a global mutex:

System.Threading.Mutex mutex = new System.Threading.Mutex();

And put these lines around each of these possible problem areas:

mutex.WaitOne();
mutex.ReleaseMutex();

So your first label update will look like this:

mutex.WaitOne();
lblPlatformsUnIdentified.Text = unidentified.ToString();
mutex.ReleaseMutex();