2017-02-20 371 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; 
}