【问题标题】:System.AggregateException the program crashesSystem.AggregateException 程序崩溃
【发布时间】:2015-11-11 20:45:40
【问题描述】:

我不确定问题出在哪里,我认为通过搜索它是在抛出错误的“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 上崩溃,但如果我留下错误,它可能会在更多系统上崩溃。

谁能看到我做错了什么?

谢谢大家

格雷厄姆

【问题讨论】:

  • 看起来它可能是由Parallel.Foreach 代码抛出的,但由于您只记录异常消息,而不是堆栈跟踪,因此很难准确定位实际问题所在。
  • @Rhumborl 但他抓住了那个异常,没有把它扔到前面——这不应该发生。
  • @graham23s,如果代码运行单线程(简单的foreach而不是Parallel.ForEach),应用还会崩溃吗?

标签: c#


【解决方案1】:

我看到至少 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();

【讨论】:

  • 他知道哪里可以抛出异常,他问为什么那个异常没有被catch 块捕获。
  • 可能是因为多个线程同时崩溃,所以它永远不会被捕获?或者崩溃不是由处理的异常引起的?
  • 现在我想起来了,如果你想在线程中捕获异常,你的 try/catch 需要在线程内部。
  • 我认为你在这种情况下是不对的 - TPL 处理线程抛出的异常。收集异常并将 AggregateException 抛出给调用者线程,在这种情况下,应该捕获它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-30
  • 2011-10-16
  • 2020-03-14
  • 2015-08-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多