4

我试图了解如何在 .Net 中实现并行性。以下代码以Reed Copsey 博客为例。

此代码循环遍历客户集合,并在他们上次联系后 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;
    }
});

接受的答案:

思考过程是对的!正如 Cole Campbell 指出的那样,可以通过在这个特定示例中指定 ParallelOption 对象来控制和配置应该使用多少内核。这里是如何。

var parallelOptions = new ParallelOptions();
parallelOptions.MaxDegreeOfParallelism = 
                 Math.Max(Environment.ProcessorCount / 2, 1);

Parallel.ForEach 将按如下方式使用。

Parallel.ForEach(customers, parallelOptions, 
                                (customer, parallelLoopState) =>
{
    //do all same stuff
}

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

4

1 回答 1

8

The Task Parallelism Library is designed to take the system workload into account when scheduling tasks to run, so this shouldn't be an issue. However, you can use the MaxDegreeOfParallelism property on the ParallelOptions class, which can be passed into one of the overloads of ForEach(), to restrict the number of concurrent operations that it can perform, if you really need to.

于 2012-05-15T02:27:13.993 回答