【问题标题】:StackOverflow Exception C# When MultiThreading多线程时的 StackOverflow 异常 C#
【发布时间】:2018-02-17 14:01:09
【问题描述】:

我知道为什么会导致我的异常,但找不到更好的方法来解决这个问题。 到目前为止,我尝试了所有方法,但如果不更改方法,我没有得到我想要的相同结果。 Scrape(string link, Regex expression, Webclient webClient) 方法返回一个字符串列表。这段代码在没有多线程的情况下可以正常工作,但是在 1 个线程上爬行的过程真的很慢。我的目标是至少运行 15 个线程。 (我也尝试增加堆栈大小)

 private void Crawl(List<String> links)
    {
        List<String> scrapedLinks = new List<String>();

        foreach (string link in links)
        {
            List<String> scrapedItems = Scrape(link, new Regex(iTalk_TextBox_Small2.Text), new WebClient());

            foreach (string item in scrapedItems) listBox1.Invoke(new Action(delegate () { listBox1.Items.Add(item); }));
            iTalk_Label4.Invoke(new Action(delegate () { iTalk_Label4.Text = "Scraped Items: " + listBox1.Items.Count; }));

            if (scrapedItems.Count > 0 || !Properties.Settings.Default.Inspector)
            {
                foreach (string scrapedLink in Scrape(link, new Regex(@"https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)"), new WebClient()))
                {
                    if(!Properties.Settings.Default.Blacklist.Contains(scrapedLink)) scrapedLinks.Add(scrapedLink);
                }
                scrapedLinksTotal += scrapedLinks.Count;                
            }

            iTalk_Label5.Invoke(new Action(delegate () { iTalk_Label5.Text = "Scraped Links: " + scrapedLinksTotal; }));
        }

        Crawl(scrapedLinks);
    }

【问题讨论】:

  • Scrape 的每次调用都会导致scrapedLinks.CountScrape 的新调用。即使scrapedLinks.Count 不是那么大,您也会以指数方式生成线程。增加堆栈大小不会有太大帮助,因为将它乘以 scrapedLinks.Count 的平均大小只会让您多出一个循环。

标签: c# multithreading exception


【解决方案1】:

在 99% 的情况下,堆栈溢出是由无限递归引起的。在您的情况下,您在 Crawl 中无条件地调用 Crawl(scrapedLinks)。不知道 scrapedLinks 应该做什么,但这就是原因。

【讨论】:

    【解决方案2】:

    添加一个终止条件。在不深入研究 Crawl 实际执行的逻辑的情况下,也许像这样简单的事情就可以解决问题:

    private void Crawl(List<String> links)
    {
        //////////////////////////////////
        // Check for something to work on
        if (links == null || links.Count == 0)
            return; // Return if there is nothing to do.
        //////////////////////////////////
    
        List<String> scrapedLinks = new List<String>();
    
        foreach (string link in links)
        {
            List<String> scrapedItems = Scrape(link, new Regex(iTalk_TextBox_Small2.Text), new WebClient());
    
            foreach (string item in scrapedItems) listBox1.Invoke(new Action(delegate () { listBox1.Items.Add(item); }));
            iTalk_Label4.Invoke(new Action(delegate () { iTalk_Label4.Text = "Scraped Items: " + listBox1.Items.Count; }));
    
            if (scrapedItems.Count > 0 || !Properties.Settings.Default.Inspector)
            {
                foreach (string scrapedLink in Scrape(link, new Regex(@"https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)"), new WebClient()))
                {
                    if(!Properties.Settings.Default.Blacklist.Contains(scrapedLink)) scrapedLinks.Add(scrapedLink);
                }
                scrapedLinksTotal += scrapedLinks.Count;                
            }
    
            iTalk_Label5.Invoke(new Action(delegate () { iTalk_Label5.Text = "Scraped Links: " + scrapedLinksTotal; }));
        }
    
        Crawl(scrapedLinks);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-16
      • 2011-12-25
      • 1970-01-01
      相关资源
      最近更新 更多