2017-02-20 370 views
-1

我想更改/設置ConcurrentQueue中的一個值。 FixedSizedQueueConcurrentQueue。我認爲我不得不努力獲得這個ConcurrentQueue中的條目之一的主要問題。任何建議...如何更改C#中的值ConcurrentQueue

private void CalculateABC(FixedSizedQueue<Bar> q) 
{ 
    decimal sum = 0.0m; 

    foreach (var item in q.Queue) 
    { 
     sum = sum + item.close; 
    } 

     decimal ABCvalue = decimal.Round(sum/q.Limit, 5); 

     //I'm trying to set the value HERE. 
     //((Bar)(q.Queue)Items[19]).ABC = ABCvalue; 

    } 
+7

這是您的設計問題。一個隊列是這樣命名的,所以你沒有隨機存取。 – MickyD

+0

我認爲你需要解釋你想要做什麼以及爲什麼你認爲你需要一個隊列。您顯示的代碼不需要隊列。你能解釋整個問題嗎? – Enigmativity

回答

0
private void CalculateABC(FixedSizedQueue<Bar> q) 
{ 
    decimal sum = 0.0m; 

    Bar item19 = null; 
    int index = 0; 
    foreach (var item in q.Queue) 
    { 
    if (index++ == 19) 
     item19 = item; 
    sum = sum + item.close; 
    } 

    decimal ABCvalue = decimal.Round(sum/q.Limit, 5); 

    //I'm trying to set the value HERE. 
    if (item19 != null) 
    item19.ABC = ABCvalue; 
} 
+0

哎呀,忘了++ – Igor

+0

你可能應該有'++索引'。 – Enigmativity

+0

@Enigmativity - OP可以決定 – Igor

0

在我看來,你只需要做到這一點:

private void CalculateABC(FixedSizedQueue<Bar> q) 
{ 
    q.Queue.Skip(19).First().ABC = 
     decimal.Round(q.Queue.Sum(x => x.close)/q.Limit, 5); 
} 

很明顯,你必須確保你的隊列中有至少20個元素這個工作。

0

儘管您可能希望使用隊列而不是列表來重新評估(或者在本例中是ConcurrentQueue而不是ConcurrentBag),因爲它不會提供隨機訪問(並且您需要枚舉所有先前的元素以獲取到你想要的)它仍然是一個IEnumerable,所以你可以使用LINQ來索引它,但是性能會很差,因爲索引第1000個元素不需要去第一個元素+ 1000的地址,而是遍歷每個之前的999個元素。

在任何情況下,如果你想堅持用隊列和索引它與

queue.ElementAt(19) 

更換您的

queue[19] 

列舉了最簡單的解決方案,所以該完整的例子是:

private void CalculateABC(FixedSizedQueue<Bar> q) 
{ 
    // Replace your summing of each item's close property with a simple LINQ sum 
    decimal sum = q.Queue.Sum(item=>item.close); 

    decimal ABCvalue = decimal.Round(sum/q.Limit, 5); 

    // No need for any casting, you're already working on generics, it's already a Bar, don't cast a Bar to a Bar 
    q.Queue.ElementAt(19).ABC = ABCvalue; 
}