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: 352
        
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