あなたが探しているのはProducer-Consumer Modelと呼ばれるものです。チェックする URL のリストを含むリソースのプールがあり、1 つのスレッドがそのプールを埋めることができ、.NET 4 Parallel.ForEachがほとんどの作業を行う場合、消費者スレッドがそのプールからプルできます。
100 スレッドを使用することも、最適なスレッド数ではない可能性が非常に高く、タスク並列ライブラリにスレッド数を管理させてください。
以下は、リストが事前に入力され、スレッドの実行中にアイテムが追加されない場合の例です。
//Parallel.Foreach will block until it is done so you may want to run this function on a background worker.
public void StartThreads()
{
List<string> myListOfUrls = GetUrls();
Parallel.Foreach(myListOfUrls, ProcessUrl);
}
private void ProcessUrl(string url)
{
//Do your work here, this code will be run from multiple threads.
}
実行時にコレクションにデータを入力する必要がある場合は、BlockingCollectionList<string>
などの並行コレクションに置き換えます。
BlockingCollection<string> myListOfUrls = new BlockingCollection();
//Parallel.Foreach will block until it is done so you may want to run this function on a background worker.
public void StartThreads()
{
if(myListOfUrls.IsComplete == true)
{
//The collection has emptied itself and you told it you where done using it, you will either need to throw a exception or make a new collection.
//use IsCompleatedAdding to check to see if you told it that you are done with it, but there still may be members left to process.
throw new InvalidOperationException();
}
//We create a Partitioner to remove the buffering behavior of Parallel.ForEach, this gives better performance with a BlockingCollection.
var partitioner = Partitioner.Create(myListOfUrls.GetConsumingEnumerable(), EnumerablePartitionerOptions.NoBuffering);
Parallel.ForEach(partitioner, ProcessUrl);
}
public void StopThreads()
{
myListOfUrls.CompletedAdding()
}
public void AddUrl(string url)
{
myListOfUrls.Add(url);
}
private void ProcessUrl(string url)
{
//Do your work here, this code will be run from multiple threads.
}
また、自動化されたスレッドスケジューリングも最適ではない可能性があることを付け加えたいと思います。拡張できる制限がいくつかある可能性があります。元の質問のこのコメントを参照してください
100スレッドはひどい考えだと言った/賛成した人のために:私のデュアルコア2GB RAM XPマシンでは、Parallel.Foreachは(ThreadPool.SetMinThreadsを設定しない限り)5つ以上のスレッドを作成することはなく、100スレッドを作成すると常に〜30〜40%になりましたより高速な操作。したがって、すべてを Parallel.Foreach に任せないでください。PS: 私のテスト コード WebClient wc = new WebClient();var s = wc.DownloadString(url); (google のホームページ) – LB