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

本文关键字:集合 循环集合 循环 存在 是否 | 更新日期: 2023-09-27 18:30:32

我想为生产者/消费者情况实现基于循环的调度,其中使用者可能会在运行时发生变化。

一开始,我使用了一个包含所有消费者的Queue,取消排队,然后立即再次排队以获得循环集合,效果很好。每当有新消费者注册时,我只是将其排队到队列中 ->完成。

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

C# 中是否有某种我没听说过的"循环集合"?

是否存在 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),但是,这还不错,因为删除很少发生。