安全地限制并行,Foreach循环中的类调用数

时间:2012-04-11 23:28:34

标签: c# multithreading

我有一个简单的foreach循环,它基于while循环和静态int来限制自己。如果我不限制它,我的CPU保持在10%以下,如果我限制它我的CPU上升到99/100%。如何在Paralell.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--;
            }
        }
    }
});

我需要限制它,是的我理解Max Parallelism有自己的限制,但是,在服务器中的CPU达到该限制之前,我的交换机陷入困境。

2 个答案:

答案 0 :(得分:2)

两件事:

1)您似乎没有使用您在此示例中创建的ParallelOptions()

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

答案 1 :(得分:1)

  

我有一个简单的foreach循环,它基于while循环限制自己   和一个静态的int。如果我不限制它,如果我,我的CPU保持在10%以下   限制它我的CPU上升到99/100%。

这很奇怪。这可能是您通过循环限制并发性的方式的结果,顺便说一下,这似乎会导致每个drow被抓取多次。我怀疑那是你想要的。由于爬网操作是IO绑定,因此CPU利用率较低。

如果您确实要将MasterCrawlBegin的并发呼叫数限制为9,请设置MaxDegreesOfParallelism = 9whileTotalThreads的{​​{1}}循环和维护不起作用。作为旁注,您将以非线程安全的方式递增和递减计数器。

将您的代码更改为这样。

ActiveThreads