2010-05-07 3 views
2

최근 보고서에서 누적 합계를 수행해야했습니다. 각 그룹에 대해 행을 정렬 한 다음 그룹 내의 이전 행을 기준으로 누적 합계를 계산합니다. 아하! PLINQ의 완벽한 사용 사례라고 생각했습니다.PLINQ를 사용하여 인클로저 내의 값을 계산하고 업데이트하지 마십시오.

그러나 코드를 작성하면 몇 가지 이상한 동작이 나타납니다. 내가 수정 한 값은 디버거를 밟을 때 수정 된 것으로 표시되었지만 액세스 할 때는 항상 0이었습니다.

샘플 코드 :

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

내가 .ToArray() 것으로 확인에 대한 선택을 변경하면

, 그것은 잘 작동하고 나는 reuslts을 계산 얻을.

내가 잘못하고있는 아이디어가 있습니까?

+0

코드를 올바르게 입력하고 시도하십시오. – ntziolis

+0

알아두면 저장시 오류가 발생하며이를 살펴볼 때 형식이 지정되지 않았습니다. 나는 편집을 누른 다음 저장하고 POW를 마술처럼 개혁했습니다. :) – Keith

답변

4

PLINQ 쿼리를 실행하면 "found"IEnumerable<T>이 완전히 실행되지 않습니다. 기본적으로 LINQ to Objects는 지연 실행을 사용하므로 PLINQ 쿼리가 해당 위치에 도달 할 때까지 "Found"의 각 요소가 만들어지지 않습니다.

ForAll 메서드는 내부적으로 찾음을 사용하여 실행되므로 실행되지 않거나 부분적으로 열거 된 시퀀스가 ​​나타납니다. .ForArll 호출 전에 .ToArray() (또는 ToList - 기본적으로 LINQ to Objects 쿼리를 강제 실행하는 모든 항목)를 추가하면 LINQ to Objects 쿼리가 실행되어 PLINQ 쿼리가 제대로 실행될 수 있습니다 .