0

n が順序付けられたキーによって定義されている n 番目の要素で再キューイングが必要です。

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


 queue.RequeueByOrderedKey(key, element)

また

 queue.RequeueN(index, element)

…これは自分で実装する必要がありそうなので、publicベースのものを検討中

  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;
        }
    }
4

2 に答える 2

1

BlockingCollectionを使用してこれを行うことができます。インデックス可能なキューを作成し、IProducerConsumerCollectionを実装します。この方法の使用方法についてBlockingCollectionは、私の記事「ブロッキングコレクションのカスタマイズ」で説明しています。この記事ではスタックを使用していますが、スタックをインデックス可能なキューに簡単に置き換えることができます。

別の方法として、同時優先キューがあります。ヒープとロックを備えた単純なものを作成できます。私の記事AGenericBinaryHeapを参照してください。同期を追加する必要があります。

于 2012-04-15T15:19:21.227 に答える
1

いいえ、それは不可能です。これは のエッセンスであるためqueue、キーまたはインデックスにアクセスすることはできません。これには a を使用List<>します。

于 2012-04-15T07:40:39.210 に答える