无尽循环不断创建新线程

本文关键字:线程 新线程 创建 循环 无尽 | 更新日期: 2023-09-27 18:27:08

我目前正在用C#编写一个基本的网络爬虫。它是多线程的,但以目前的结构,它不断地在一个无休止的循环中创建线程。我应该在这个代码中更改什么:

爬行器:

public static void Start(Uri url)
    {
        if (!RobotsParser.IsDomainParsed(LinkParser.GetDomainUrl(url)))
        {
            RobotsParser.Parse(url);
        }
        if (!CrawlQueue.CrawledList.Contains(url) && RobotsParser.IsCrawlingAllowed(url.ToString()))
        {
            CrawlQueue.CrawledList.Add(url);
            CrawlQueue.QueueList.Remove(url);
            //Crawling logic happens here...
            CrawlQueue.Add(LinkParser.Find(doc, responseUri));
            }
        }
    }

链接分析器:

public static HashSet<Uri> Find(HtmlDocument doc, string url)
{
   //returns list of found urls
    return list;
}

队列(这就是问题所在)

internal static class CrawlQueue
{
    public static HashSet<Uri> QueueList = new HashSet<Uri>();
    public static HashSet<Uri> CrawledList = new HashSet<Uri>();
    private static void Start()
    {
        Parallel.ForEach(QueueList.ToList(), new ParallelOptions { MaxDegreeOfParallelism = 7 }, url =>
        {
            try { CrawlEngine.Start(url); }
            catch (Exception e) { Debug.WriteLine(url + " "+ e.ToString()); }
        });
    }
    public static void Add(HashSet<Uri> list)
    {
        int counter = 0;
        foreach (var site in list.Where(site => !QueueList.Contains(site)))
        {
            QueueList.Add(site);
            counter++;
        }
        if (counter >= 1)
        {
            Logging.Log(counter + " items added to crawling queue");
            Start();
        }
    }
}

在浏览列表时,我应该采用什么样的设计?

无尽循环不断创建新线程

许多线程被派生的问题是对Start()Parallel.ForEach的递归调用(阻塞调用)。您应该使用类似Task.Factory.StartNew()的东西,以允许在子任务运行时退出对Start()的调用。您可能需要重构代码以返回生成的任务,这样您就可以知道什么时候完成了所有任务。

正如评论所提到的,您可能不需要阻塞多线程解决方案(您应该使用非阻塞IO),但这是一个更大的变化。