是否存在 C#“循环集合”
本文关键字:集合 循环集合 循环 存在 是否 | 更新日期: 2023-09-27 18:30:32
我想为生产者/消费者情况实现基于循环的调度,其中使用者可能会在运行时发生变化。
一开始,我使用了一个包含所有消费者的Queue
,取消排队,然后立即再次排队以获得循环集合,效果很好。每当有新消费者注册时,我只是将其排队到队列中 ->完成。
但是,在运行时(当他们发送取消订阅消息时)删除使用者的问题具有挑战性。队列不提供 Remove() 方法,但是,我需要将它们从队列中完全删除 - 独立于消费者在队列中的当前位置。显然,Queue
"界面"并不是我所需要的。
C# 中是否有某种我没听说过的"循环集合"?
从队列中间删除内容是一团糟:您最终会迭代所有项目,并仅重新排队您不想删除的项目。这样的事情可能会起作用:
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)
的方式包装取消排队方法,排队除了实际排队之外,还需要从toRemove
中删除item
,而取消排队需要额外检查项目是否存在toRemove
。
当然,您始终可以实现自己的循环缓冲区,只需将缓冲区从后向前移动,将要保留的项目复制到自身上,并在完成后调整"head"指针,即可从中间删除项目。
在阅读了dasblinkenlight的回答之后,我现在使用基于LinkedList
的方法。
- AddConsumer -> linkedList.AddLast
- 删除消费者 ->链接列表。删除
-
获取下一个消费者
var next = linkedList.First.Value;linkedList.RemoveFirst();linkedList.AddLast(next);返回下一个;
这确实可以解决问题,RemoveConsumer是O(N),但是,这还不错,因为删除很少发生。