我试图理解并行性是如何在.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
}
相同的概念可以应用于 PLINQ 使用 。WithDegreeOfParallelism(int numberOfThreads(.有关如何配置并行选项的详细信息,请阅读此内容。
任务并行库旨在在计划要运行的任务时考虑系统工作负载,因此这应该不是问题。 但是,您可以在 ParallelOptions
类上使用 MaxDegreeOfParallelism
属性,该属性可以传递到 ForEach()
的一个重载中,以限制它可以执行的并发操作数(如果确实需要(。