c# - 使用 PLINQ 计算和更新机箱内的值不起作用

标签 c# c#-4.0 plinq

我最近需要对报告进行汇总。对于每个组,我对行进行排序,然后根据组内之前的行计算运行总计。啊哈!我想,这是 PLINQ 的完美用例!

但是,当我编写代码时,我遇到了一些奇怪的行为。我正在修改的值在单步执行调试器时显示为已修改,但当它们被访问时它们始终为零。

示例代码:

class Item
{
 public int PortfolioID;
 public int TAAccountID;
 public DateTime TradeDate;
 public decimal Shares;
 public decimal RunningTotal;
}

List<Item> itemList = new List<Item>
{
 new Item
 {
  PortfolioID = 1,
  TAAccountID = 1,
  TradeDate = new DateTime(2010, 5, 1),
  Shares = 5.335m,
 },
 new Item
 {
  PortfolioID = 1,
  TAAccountID = 1,
  TradeDate = new DateTime(2010, 5, 2),
  Shares = -2.335m,
 },
 new Item
 {
  PortfolioID = 2,
  TAAccountID = 1,
  TradeDate = new DateTime(2010, 5, 1),
  Shares = 7.335m,
 },
 new Item
 {
  PortfolioID = 2,
  TAAccountID = 1,
  TradeDate = new DateTime(2010, 5, 2),
  Shares = -3.335m,
 },

};

var found = (from i in itemList
   where i.TAAccountID == 1
   select new Item
   {
    TAAccountID = i.TAAccountID,
    PortfolioID = i.PortfolioID,
    Shares = i.Shares,
    TradeDate = i.TradeDate,
    RunningTotal = 0
   });

found.AsParallel().ForAll(x =>
{
 var prevItems =  found.Where(i => i.PortfolioID == x.PortfolioID
  && i.TAAccountID == x.TAAccountID 
  && i.TradeDate <= x.TradeDate);
 x.RunningTotal = prevItems.Sum(s => s.Shares);
});

foreach (Item i in found)
{
 Console.WriteLine("Running total: {0}", i.RunningTotal);
}

Console.ReadLine();

如果我将 find 的选择更改为 .ToArray(),那么它工作正常,并且我会得到计算结果。

知道我做错了什么吗?

最佳答案

当您的 PLINQ 查询执行时,“找到”IEnumerable<T>尚未完全执行。由于 LINQ to Objects 默认情况下使用延迟执行,因此在 PLINQ 查询到达该位置之前,不会创建“Found”的每个元素。

由于 ForAll 方法在内部使用 find 执行,因此它会得到一个未执行的或仅部分枚举的序列。通过在 .ForAll 调用之前添加 .ToArray() (或 ToList - 基本上是强制执行 LINQ to Objects 查询的任何内容),您将强制执行 LINQ to Objects 查询,从而允许 PLINQ 查询正确执行.

关于c# - 使用 PLINQ 计算和更新机箱内的值不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2789672/

相关文章:

C# 图表适合一个选项卡

c# - 使用私钥将 X509Certificate2 导出到字节数组

c# - 如何在列表中查找属性具有特定值或存在具有该值的相关项目的所有项目?

c#-4.0 - 如何将多个对象插入到Azure移动服务表 Controller [.Net后端]

c# - 这个 lambda 函数是如何工作的?

c# - 修改基础列表时的 PLINQ O(n^2)

c# - 使用 TPL 的推测执行

c# - 根据 ASP.NET 查询从模型返回部分列表

winforms - 动态地将列和行添加到 tablelayoutpanel 行中

.net - 如何使 PLINQ 在 .NET 4.0 beta 2 中产生更多并发线程?