Using PLINQ to calculate and update values within the enclosure does not work

Posted by Keith on Stack Overflow See other posts from Stack Overflow or by Keith
Published on 2010-05-07T15:24:23Z Indexed on 2010/05/07 15:28 UTC
Read the original article Hit count: 259

Filed under:
|
|

I recently needed to do a running total on a report. Where for each group, I order the rows and then calculate the running total based on the previous rows within the group. Aha! I thought, a perfect use case for PLINQ!

However, when I wrote up the code, I got some strange behavior. The values I was modifying showed as being modified when stepping through the debugger, but when they were accessed they were always zero.

Sample Code:

 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();

If I change the select for found to be .ToArray(), then it works fine and I get calculated reuslts.

Any ideas what I am doing wrong?

© Stack Overflow or respective owner

Related posts about c#

Related posts about PLINQ