我想为生产者/消费者情况实施基于循环的调度,消费者可能会在运行时期间进行更改。
在开始时,我使用了一个Queue
,其中包含所有消费者,将其中一个出列并立即将其排队以获得圆形集合,完美运行。每当新的消费者注册时,我只是将其排队到队列中 - >完成。
然而,在运行时删除消费者(当他们发送取消订阅消息时)的问题具有挑战性。 Queue不提供Remove()方法,但是,我需要将它们从队列中完全删除 - 与消费者在队列中的当前位置无关。显然Queue
“界面”并不是我需要的。
C#中是否有某种“循环收藏”我还没有听说过?
答案 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
的方法。
GetNextConsumer
var next = linkedList.First.Value; linkedList.RemoveFirst(); linkedList.AddLast(下); 返回下一步;
这就是诀窍,RemoveConsumer是O(N),然而,这并不算太糟糕,因为删除很少发生。