关于c#中并行化的几个问题

时间:2013-10-12 14:54:15

标签: c# parallel-processing

我在c#中写了一个沉重的网络刮刀。我希望它快速可靠。 Parallel.Foreach和Parallel.For对于这个来说太慢了。 对于输入,我使用的是URL列表。我希望在同一时间有多达300个线程工作(我的cpu和网络连接可以处理这个)。最好的方法是什么?使用任务会更好吗? 有时线程没有明显的原因结束,有些结果没有得到保存。我想要一种更可靠的方法来做到这一点。有任何想法吗? 我希望有一个更稳固的队列类型的抓取。 我想出了什么(不是所有代码,而是重要部分):

        List <string> input = // read text file
        int total = words.Length;
        int maxThreads = 300;

        while (true)
        {
            if (activeThreads < maxThreads)
            {
               current++;
               Thread thread = new Thread(() => CrawlWebsite(words[current]));
               thread.Start();
            }
        }

        public static void CrawlWebsite(string word)
        {
            activeThreads++;

            // scraping part

            activeThreads--;
        }

2 个答案:

答案 0 :(得分:1)

考虑使用System.Threading.ThreadPool。对于具有许多线程的场景,它可能会快一点,并且您不需要管理activeThreads。相反,你可以使用ThreadPool.SetMaxThreads()和SetMinThreads(),ThreadPool为你管理并行线程的数量。

顺便说一句,您的示例中缺少共享变量的同步。同步访问的方法之一是使用“锁定” - 请参阅http://msdn.microsoft.com/en-us/library/c5kehkcz.aspx

您的线程运行方法--CrawlWebsite()应该处理ThreadAbortException - 请参阅http://msdn.microsoft.com/en-us/library/system.threading.threadabortexception.aspx

答案 1 :(得分:1)

我最近在处理非常类似的问题,并且不认为使用任何大量的线程会使它更快。最慢的想法通常是下载数据。拥有大量线程并不会让它变得更快,因为大多数人都在等待网络连接数据传输等。所以我最终得到了两个队列。一个是由少量线程处理的,这些线程只发送异步下载请求(一次10-15个请求)。响应存储在另一个队列中,该队列进入另一个负责解析和数据处理的线程池(此处的线程数取决于您的CPU和处理算法)。

我还将所有下载的数据保存到数据库中。任何时候我想从网上实现一些新信息的解析我不需要重新下载内容,但只能从数据库中解析缓存的网页(这节省了时间)