.Net中的Parallelism可以接管CPU并可能拒绝其他进程的服务吗?

Imr*_*jad 4 .net c# parallel-processing task-parallel-library c#-4.0

我试图了解如何在.Net中实现Parallelism.以下代码以Reed Copsey Blog为例.

此代码循环遍历客户集合,并在上次联系后的14天后向他们发送电子邮件.我的问题是,如果客户表非常大并且发送电子邮件需要几秒钟,这个代码不会将CPU拒绝服务模式带到其他重要流程吗?

有没有办法并行运行以下代码行,但只使用少量内核,以便其他进程可以共享CPU?或者我是以错误的方式解决问题?

Parallel.ForEach(customers, (customer, parallelLoopState) =>
{
    // database operation
    DateTime lastContact = theStore.GetLastContact(customer); 
    TimeSpan timeSinceContact = DateTime.Now - lastContact;

    // If it's been more than two weeks, send an email, and update...
    if (timeSinceContact.Days > 14)
    {
         // Exit gracefully if we fail to email, since this 
         // entire process can be repeated later without issue.
         if (theStore.EmailCustomer(customer) == false)
             parallelLoopState.Break();
         else
             customer.LastEmailContact = DateTime.Now;
    }
});
Run Code Online (Sandbox Code Playgroud)

一般承认的答案:

思维过程是正确的!正如Cole Campbell指出的那样,通过在此特定示例中指定ParallelOption对象,可以控制和配置应该使用多少个核心.这是怎么回事.

var parallelOptions = new ParallelOptions();
parallelOptions.MaxDegreeOfParallelism = 
                 Math.Max(Environment.ProcessorCount / 2, 1);
Run Code Online (Sandbox Code Playgroud)

Parallel.ForEach将如下使用.

Parallel.ForEach(customers, parallelOptions, 
                                (customer, parallelLoopState) =>
{
    //do all same stuff
}
Run Code Online (Sandbox Code Playgroud)

可以使用.WithDegreeOfParallelism(int numberOfThreads)将相同的概念应用于PLINQ.有关如何配置并行选项的更多信息,请阅读此内容.

Col*_*ell 8

任务并行库旨在在计划要运行的任务时考虑系统工作负载,因此这不应成为问题.但是,如果确实需要,可以使用类MaxDegreeOfParallelism上的属性(ParallelOptions可以将其传递到其中一个重载中ForEach())来限制它可以执行的并发操作数.