1

Web ページ用の単純なクローラーを開発しています。マルチスレッドクローラーを実装するための多くのソリューションを検索して見つけました。一意の URL を含むスレッドセーフなキューを作成する最良の方法は何ですか?

編集: .Net 4.5 でより良い解決策はありますか?

4

5 に答える 5

2

ConcurrentQueueは、実際、フレームワークのスレッドセーフキューの実装です。ただし、プロデューサー/コンシューマーのシナリオで使用する可能性が高いため、実際に必要なクラスは、非常に便利なBlockingCollectionである可能性があります。

于 2012-04-10T11:21:53.250 に答える
2

Task Parallel Libraryを使用し、ThreadPool を使用するデフォルトのスケジューラを使用します。


OK、これは一度に 30 個の URL をキューに入れる最小限の実装です。

    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();

    }
于 2012-04-10T10:45:52.407 に答える
1

System.Collections.Concurrent.ConcurrentQueue<T>法案に適合しますか?

于 2012-04-10T10:51:41.237 に答える
1

System.Collections.Concurrent.ConcurrentQueueを使用します。

複数のスレッドから安全にキューに入れたり、デキューしたりできます。

于 2012-04-10T10:52:21.130 に答える
1

System.Collections.Concurrent.ConcurrentQueue を見てください。待つ必要がある場合は、System.Collections.Concurrent.BlockingCollection を使用できます。

于 2012-04-10T11:13:50.893 に答える