2

while ループと static int に基づいて自分自身を制限する単純な foreach ループがあります。制限しない場合、CPU は 10% 未満のままです。制限すると、CPU は 99/100% になります。Parallell.Foreach 内のクラスへの呼び出しの数を安全に制限するにはどうすればよいですか?

static int ActiveThreads { get; set; }
static int TotalThreads { get; set; }

var options = new ParallelOptions();
options.MaxDegreeOfParallelism = 1;
Parallel.ForEach(urlTable.AsEnumerable(),options,drow =>
{
    using (var WCC = new MasterCrawlerClass())
    {
        while (TotalThreads <= urlTable.Rows.Count)
        {
            if (ActiveThreads <= 9)
            {
                Console.WriteLine("Active Thread #: " + ActiveThreads);
                ActiveThreads++;
                WCC.MasterCrawlBegin(drow);
                TotalThreads++;
                Console.WriteLine("Done Crawling a datarow");
                ActiveThreads--;
            }
        }
    }
});

私はそれを制限する必要があります。はい、最大並列処理には独自の制限があることを理解していますが、サーバーの CPU がその制限に達する前にスイッチが動かなくなります。

4

2 に答える 2

2

2つのこと:

ParallelOptions()1)この例で作成した を使用していないようです。

2)Semaphore何らかの理由で を使用したくない場合は、 を使用できますParallelOptions

 Semaphore sm = new Semaphore(0, 9);

 // increment semaphore or block if = 9
 // this will block gracefully without constantly checking for `ActiveThreads <= 9`
 sm.WaitOne();

 // decrement semaphore
 sm.Release();
于 2012-04-11T23:45:26.313 に答える
1

while ループと static int に基づいて自分自身を制限する単純な foreach ループがあります。制限しない場合、CPU は 10% 未満のままです。制限すると、CPU は 99/100% になります。

それはかなり奇妙です。これは、ループで同時実行性を制限した結果である可能性があります。これにより、それぞれdrowが何度もクロールされるように見えます。それがあなたの望んでいることだとは思えません。クロール操作が IO バウンドであるため、CPU 使用率が低下しています。

同時呼び出しの数を本当に 9 に制限したい場合は、 をMasterCrawlBegin設定しMaxDegreesOfParallelism = 9ます。andのwhileループとメンテナンスTotalThreadsは機能しActiveThreadsません。補足として、スレッドセーフではない方法でカウンターをインクリメントおよびデクリメントしています。

コードを次のように変更します。

int ActiveThreads = 0;
var options = new ParallelOptions(); 
options.MaxDegreeOfParallelism = 9; 
Parallel.ForEach(urlTable.AsEnumerable(),options,drow => 
{
  int x = Interlocked.Increment(ref ActiveThreads);
  Console.WriteLine("Active Thread #: " + x); 
  try
  {
    using (var WCC = new MasterCrawlerClass()) 
    { 
      WCC.MasterCrawlBegin(drow); 
    }
  }
  finally
  {
    Interlocked.Decrement(ref ActiveThreads);
    Console.WriteLine("Done Crawling a datarow"); 
  } 
}); 
于 2012-04-12T02:14:17.680 に答える