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.有关如何配置并行选项的更多信息,请阅读此内容.
任务并行库旨在在计划要运行的任务时考虑系统工作负载,因此这不应成为问题.但是,如果确实需要,可以使用类MaxDegreeOfParallelism上的属性(ParallelOptions可以将其传递到其中一个重载中ForEach())来限制它可以执行的并发操作数.