需要 n 处重新排队 ConcurrentQueue<> 方法

本文关键字:ConcurrentQueue 方法 排队 新排队 需要 | 更新日期: 2023-09-27 18:31:13

我需要在第n个元素处重新排队,其中n由有序键定义。

 ConcurrentQueue<KeyValuePair<string, SomeClass>> queue = new ConcurrentQueue<KeyValuePair<string, SomeClass>>();

 queue.RequeueByOrderedKey(key, element)

 queue.RequeueN(index, element)

。由于看起来有必要自己实现这一点,所以我正在考虑基于公共的东西

  class Class1 : KeyedCollection<K,V>{}
   it'd be nice to have Class1 : OrderedKeyedCollection<K,V>{}

这是我做的一些代码。 我会把它放在这里征求意见,然后可能会把它作为一个答案。 可能还没有正确处理并发的东西。

    public class QueueExt<TK, TV> : SortedList<TK, TV> {
        #region Constructors
        public QueueExt(Func<TV, TK> getKey = null) {
            GetKey = getKey;
        }
        private Func<TV, TK> GetKey = null;
        public QueueExt(int capacity, Func<TV, TK> getKey = null)
            : base(capacity) {
            GetKey = getKey;
        }
        public QueueExt(IComparer<TK> comparer, Func<TV, TK> getKey = null)
            : base(comparer) {
            GetKey = getKey;
        }
        public QueueExt(int capacity, IComparer<TK> comparer, Func<TV, TK> getKey = null)
            : base(capacity, comparer) {
            GetKey = getKey;
        }
        public QueueExt(IDictionary<TK, TV> dictionary, Func<TV, TK> getKey = null)
            : base(dictionary) {
            GetKey = getKey;
        }
        public QueueExt(IDictionary<TK, TV> dictionary, IComparer<TK> comparer, Func<TV, TK> getKey = null)
            : base(dictionary, comparer) {
            GetKey = getKey;
        }
        #endregion
        public TV Dequeue() {
            lock (this) {
                var first = this.ElementAt(0).Value;
                this.RemoveAt(0);
                return first;
            }
        }
        public void Requeue() {
            if (GetKey == null)
                throw new ArgumentNullException("Key getter lamda must not be null");
            lock (this) {
                var key = this.ElementAt(0).Key;
                var actualkey = GetKey(this.ElementAt(0).Value);
                if (!actualkey.Equals(key)) {
                    this.Enqueue(this.Dequeue());
                }
            }
        }
        public void Enqueue(TK key, TV item) {
            this.Add(key, item);
        }
        public void Enqueue(TV item) {
            if (GetKey == null)
                throw new ArgumentNullException("Key getter lamda must not be null");
            var key = GetKey(item);
            this.Add(key, item);
        }
        public TV Peek() {
            return this.ElementAt(0).Value;
        }
    }

需要 n 处重新排队 ConcurrentQueue<> 方法

你可以用 BlockingCollection 来做到这一点。创建可索引队列并使其实现 IProducerConsumerCollection。我在我的文章自定义阻止集合中展示了如何使用BlockingCollection。我在文章中使用了堆栈,但您可以轻松地将堆栈替换为可索引队列。

另一种方法是并发优先级队列。您可以构建一个带有堆和锁的简单工具。请参阅我的文章 A Generic Binary Heap。您需要添加同步。

不,这是不可能的,因为它是queue的,你不能有密钥或索引访问它。为此使用List<>