[英]AsParallel() executing sequentially
我有以下PLINQ查询:
// Let's get a few customers
List<Customer> customers = CustomerRepository.GetSomeCustomers();
// Let's get all of the items for all of these customers
List<CustomerItem> items = customers
.AsParallel()
.SelectMany(x => ItemRepository.GetItemsByCustomer(x))
.ToList();
我希望GetItemsByCustomer()
将为每个客户并行执行, 但是会顺序运行 。
我试图强制并行化,但是仍然没有运气:
List<CustomerItem> items = customers
.AsParallel()
.WithExecutionMode(ParallelExecutionMode.ForceParallelism)
.SelectMany(x => ItemRepository.GetItemsByCustomer(x))
.ToList();
方法签名:
private IEnumerable<Item> GetItemsByCustomer(Customer customer)
{
// Get all items for a customer...
}
根据本文 ,如果PLINQ认为合适,当然可以采用顺序路由,但是强制并行性仍应优先于此。
注意:上面的示例纯粹是示例性的-假设customers
是一个很小的列表,而GetItemsByCustomer
是一个昂贵的方法。
AsParallel()
没有错。 如果可能,它将以并行方式运行,并且LINQ表达式中没有顺序依赖关系,因此没有什么可以强迫它顺序运行。
您的代码无法并行运行的几个原因可能是:
您的机器/ VM具有单个CPU,或者具有.NET设置以将并行性限制为一个CPU。 您可以使用以下代码进行模拟:
var customers = new List<Customer>() { new Customer() {Name = "Mick", Surname = "Jagger"}, new Customer() {Name = "George", Surname = "Clooney"},new Customer() {Name = "Kirk", Surname = "DOuglas"}}; var items = customers .AsParallel() .SelectMany(x => { Console.WriteLine("Requesting: " + x.Name + " - " + DateTime.Now); Thread.Sleep(3000); return new List<CustomerItem>(); }) .WithDegreeOfParallelism(1) .ToList();
即使您在单个内核/ CPU盒上使用WithExecutionMode(ParallelExecutionMode.ForceParallelism)
强制WithExecutionMode(ParallelExecutionMode.ForceParallelism)
,或者当并行度为1时,您的设置也不会生效,因为不可能进行真正的并行化。
存储库中发生一些线程锁定共享资源的情况。 您可以使用以下代码模拟线程锁定:
var customers = new List<Customer>() { new Customer() {Name = "Mick", Surname = "Jagger"}, new Customer() {Name = "George", Surname = "Clooney"},new Customer() {Name = "Kirk", Surname = "DOuglas"}}; var locker = new object(); // Let's get all of the items for all of these customers var items = customers .AsParallel() .SelectMany(x => { lock (locker) { Console.WriteLine("Requesting: " + x.Name + " - " + DateTime.Now); Thread.Sleep(3000); return new List<CustomerItem>(); } }) .ToList();
在某些情况下,有一些数据库设置会强制查询/读取是连续的,这可能会给您一种印象,即C#代码实际上不是并行运行的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.