2012-04-10 101 views
1

我正在为网页开发一个简单的爬虫程序。我搜索了一个发现了很多实现多线程爬虫的解决方案。创建线程安全队列以包含唯一URL的最佳方式是什么?.NET中的多线程C#队列4

编辑: 在.Net 4.5中有更好的解决方案吗?

+0

[用于编写多线程C#爬虫的.Net 4.5中的类]的可能重复(http://stackoverflow.com/questions/10086408/classes-in-net-4-5-for-writing-a-多线程c-sharp-crawler) – 2012-04-10 10:49:22

+1

好!所以我去那里发布一个问题,很少有人投票结束,因为它不在一个地区。我来这里把它张贴在一个区域,现在你说它是重复的!我认为无论我做什么,有些人想试图解决问题。这比回答容易,对吧?! – 2012-04-10 10:53:05

+1

您应该考虑删除覆盖多个区域的旧问题。这样,这一个不会被关闭作为其他问题的副本:) – 2012-04-10 11:01:36

回答

2

使用Task Parallel Library并使用使用ThreadPool的默认调度程序。


OK,这是一个最小实现它一次排队30个网址:

public static void WebCrawl(Func<string> getNextUrlToCrawl, // returns a URL or null if no more URLs 
     Action<string> crawlUrl, // action to crawl the URL 
     int pauseInMilli // if all threads engaged, waits for n milliseconds 
     ) 
    { 
     const int maxQueueLength = 50; 
     string currentUrl = null; 
     int queueLength = 0; 

     while ((currentUrl = getNextUrlToCrawl()) != null) 
     { 
      string temp = currentUrl; 
      if (queueLength < maxQueueLength) 
      { 
       Task.Factory.StartNew(() => 
        { 
         Interlocked.Increment(ref queueLength); 
         crawlUrl(temp); 
        } 
        ).ContinueWith((t) => 
        { 
         if(t.IsFaulted) 
          Console.WriteLine(t.Exception.ToString()); 
         else 
          Console.WriteLine("Successfully done!"); 
         Interlocked.Decrement(ref queueLength); 
        } 
        ); 
      } 
      else 
      { 
       Thread.Sleep(pauseInMilli); 
      } 
     } 
    } 

假用法:

static void Main(string[] args) 
    { 
     Random r = new Random(); 
     int i = 0; 
     WebCrawl(() => (i = r.Next()) % 100 == 0 ? null : ("Some URL: " + i.ToString()), 
      (url) => Console.WriteLine(url), 
      500); 

     Console.Read(); 

    } 
+0

那么新的.Net 4.5呢? .Net 4.5中有更好的解决方案吗?你能不能请一个样品? – 2012-04-10 10:50:08

+0

@AlirezaNoori 4.5尚未正式推出,那么这对你有什么帮助?虽然'async'和'wait'关键字将有所帮助,我不知道有任何新类可以提供帮助。 – Aliostad 2012-04-10 11:07:47

+0

我正在为我的研究开发此应用程序。所以这不是问题。我在Windows 8中使用了'async'编码,但是您认为使用'async'比多线程更好吗? – 2012-04-10 11:37:52

1

System.Collections.Concurrent.ConcurrentQueue<T>符合该法案?

+0

谢谢。 .Net 4.5中有更好的解决方案吗?你可以请张贴一个简单的样本吗? – 2012-04-10 10:54:59

1

我会使用System.Collections.Concurrent.ConcurrentQueue。

您可以安全地排队和从多个线程出列队列。

1

看看System.Collections.Concurrent.ConcurrentQueue。如果您需要等待,您可以使用System.Collections.Concurrent.BlockingCollection

2

ConcurrentQueue确实是框架的线程安全队列实现。但是,由于您可能在producer-consumer的情况下使用它,因此您真正参加的课程可能是无限有用的BlockingCollection

+0

您能否发表一个非常快速的样本?谢谢 – 2012-04-10 11:33:12

+0

转到我给BlockingCollection的链接。在底部,您会发现一个简单的使用示例。 – 2012-04-10 11:56:55