System.AggregateException程序崩溃

时间:2015-11-11 20:45:40

标签: c#

我不确定问题究竟在哪里,我想通过搜索" Parallel.ForEach"抛出错误,在几个系统上程序运行正常,但在我的VPS上,应用程序每次都会崩溃几秒钟。

    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);
        }
    }

技术细节是:

  

问题签名:

     

问题事件名称:CLR20r3

     

问题签名01:wraithplatformidentifier.exe

     

问题签名02:1.0.0.1

     

问题签名03:563f8d36

     

问题签名04:系统

     

问题签名05:4.0.30319.17929

     

问题签名06:4ffa5c88

     

问题签名07:23f8

     

问题签名08:59

     

问题签名09:System.AggregateException

     

操作系统版本:6.1.7601.2.1.0.274.10

     

区域设置ID:1033

     

附加信息1:0a9e

     

其他资料2:0a9e372d3b4ad19135b953a78882e789

     

其他资料3:0a9e

     

其他资料4:0a9e372d3b4ad19135b953a78882e789

它只会在VPS上崩溃,但如果我遗漏了错误,它可能会出现在更多系统上。

谁能看到我做错了什么?

谢谢你们

格雷厄姆

1 个答案:

答案 0 :(得分:0)

我看到至少有3个潜在的线程不安全的地方。

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

这些控件可能会被不同的线程同时更改。

platforms[platform] = urls;

看起来平台是全球列表。多个线程可能正在尝试更新相同的索引。

要快速测试,请创建一个全局互斥:

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

并将这些线放在这些可能的问题区域中:

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

所以你的第一个标签更新将如下所示:

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