是否存在C#“循环集合”?

时间:2013-09-08 16:28:00

标签: c# collections

我想为生产者/消费者情况实施基于循环的调度,消费者可能会在运行时期间进行更改。

在开始时,我使用了一个Queue,其中包含所有消费者,将其中一个出列并立即将其排队以获得圆形集合,完美运行。每当新的消费者注册时,我只是将其排队到队列中 - >完成。

然而,在运行时删除消费者(当他们发送取消订阅消息时)的问题具有挑战性。 Queue不提供Remove()方法,但是,我需要将它们从队列中完全删除 - 与消费者在队列中的当前位置无关。显然Queue界面”并不是我需要的。

C#中是否有某种“循环收藏”我还没有听说过?

2 个答案:

答案 0 :(得分:2)

从队列中间删除东西是一团糟:你最终会迭代所有项目,并且只重新排队那些你不想删除的项目。这样的事情可能有用:

int count = q.Count;
for (int i = 0 ; i != count ; i++) {
    var item = q.Dequeue();
    if (!toRemove.Equals(item)) {
        q.Enqueue(item);
    }
}

但是,这需要遍历整个队列,因此它是O(n)。更好的方法可能是保留已删除项目的HashSet<T> toRemove,并将出列方法包装起来,以便快速删除项目toRemove.Add(removedItem),排队需要从item中删除toRemove {1}}除了实际入队和出列外,还需要额外检查项目是否存在toRemove

当然,您可以随时实施自己的circular buffer,只需将缓冲区移回前方,复制您希望保留的项目,然后调整'你完成后会指着头。

答案 1 :(得分:0)

在阅读了dasblinkenlight的回答之后,我现在正在使用基于LinkedList的方法。

  • AddConsumer - &gt; linkedList.AddLast
  • RemoveConsumer - &gt; linkedList.Remove
  • GetNextConsumer

    var next = linkedList.First.Value; linkedList.RemoveFirst(); linkedList.AddLast(下); 返回下一步;

这就是诀窍,RemoveConsumer是O(N),然而,这并不算太糟糕,因为删除很少发生。