2012-04-10 68 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