我在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--;
}
答案 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和处理算法)。
我还将所有下载的数据保存到数据库中。任何时候我想从网上实现一些新信息的解析我不需要重新下载内容,但只能从数据库中解析缓存的网页(这节省了时间)