2

私は 3 に制限することを想定しているセマフォを持っていますが、これは必要な数だけ呼び出し続けます。(1000)を使っているからだと思います。ただし、() だけを試してみると、WaitOne を渡すことはありません。ここで何をすべきかわかりません。

private static Semaphore _pool;
_pool = new Semaphore(0, 3);
var options = new ParallelOptions();
options.MaxDegreeOfParallelism = 1;
Parallel.ForEach(urlTable.AsEnumerable(),options, drow =>
{
    using (var WCC = new MasterCrawlerClass())
    {
                ActiveThreads++;
                _pool.WaitOne(1000);
                Console.WriteLine("Active Thread #: " + ActiveThreads);
                WCC.MasterCrawlBegin(drow);
                Console.WriteLine("Done Crawling a datarow");
                ActiveThreads--;
                _pool.Release();

    }
});
4

2 に答える 2

6

セマフォを誤解しています。に_pool = new Semaphore(3, 3);タイムアウトパラメータを渡す必要もなくなるので、実行する必要がありますWaitOne()

最初のパラメーターは、ブロックする前に許可される可能性のある要求の初期数です。したがって、0を渡すと、以降の呼び出しWaitOne()はすぐにブロックされます。

于 2012-04-12T00:32:46.873 に答える
3

ここにはいくつかの問題があります。

  • そもそも、この状況で並行性を抑制する理由はほとんどないと思います。
  • コンストラクタinitialCountで 0 に設定しています。現在許可できるリクエストの数です。SemaphoreinitialCount
  • WaitOneタイムアウト パラメータを受け入れるオーバーロードを使用しています。WaitOneセマフォからカウントが取得されたかどうかに関係なく、タイムアウトが期限切れになると返されます。
  • セマフォからカウントを取得するActiveThreads 前にインクリメントしています。これはActiveThreads、操作の同時ワーカー スレッドの数をより正確に近似することを意味しForEachます。それらのスレッドがいくつ実行されているかはわかりませんMasterCrawlBegin
  • ++操作はActiveThreadsスレッドセーフではありません。
  • MaxDegreesOfParallelismあらゆる種類の同時処理をほとんど排除する値に設定します。

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

int ActiveThreads = 0;
int ActiveCrawls = 0;
var semaphore = new SemaphoreSlim(3, 3); 
Parallel.ForEach(urlTable.AsEnumerable(), drow => 
  { 
    int x = Interlocked.Increment(ref ActiveThreads);
    Console.WriteLine("Active Thread #: " + x); 
    semaphore.Wait();
    int y = Interlocked.Increment(ref ActiveCrawls);
    Console.WriteLine("Active Crawl #: " + y); 
    try
    {
      using (var WCC = new MasterCrawlerClass()) 
      { 
        WCC.MasterCrawlBegin(drow);
      }
    }
    finally
    {
      Interlocked.Decrement(ref ActiveCrawls);
      semaphore.Release();
      Interlocked.Decrement(ref ActiveThreads);
      Console.WriteLine("Done Crawling a datarow"); 
    }
  } 
}); 

MaxDegreesOfParallelism = 3もちろん、すべてのセマフォを気にせずに設定することもできます。

于 2012-04-12T02:00:33.323 に答える