0

最近実装が必要でしたが、特定の容量に達した場合はブロックし、空の場合はIProducerConsumerCollection<T>ブロックしたかったのです。これは実際には の実装であると確信していましたが、そうではないことに気付きました。何故ですか?TryAddTryTakeBlockingCollectionIProducerConsumerCollection<T>

インターフェイスBlockingCollectionを実装するのに適していないプロパティはどれですか?IProducerConsumerCollection

BlockingCollectionそれがラッパーであることは理解していますIProducerConsumerCollectionが、関係なく、それ自体が同じインターフェイスを実装する必要があると思いました。

4

1 に答える 1

0

あなたの質問のタイトルの質問に文字通り答えるのは学術的で、それほど役に立たないようです。Jon は、その特定の質問に対する回答としてどのようなものが考えられるかについて、いくつかの洞察を提供しました。しかし、あなたが持っていると思われる根本的なニーズに対処してみましょう…

最近 IProducerConsumerCollection の実装が必要でしたが、特定の容量に達した場合は TryAdd でブロックし、空の場合は TryTake でブロックしたいと考えていました。

これらはBlockingCollectionすでに提供されている機能です。実装されていないという事実IProducerConsumerCollectionはまったく障害ではなく、そのインターフェイスが実装されていない理由も、実際に述べられている必要性に関連しているようには見えません。

  1. 「一定の容量に達したらTryAddでブロックしたかった」

メソッド ブロックをTryAdd()使用しても意味がありません。そのメソッドの全体的な理由は、非ブロッキングの追加操作 (またはタイムアウトによるブロッキング) を行うことです。つまり、追加操作を実行しようとしますが、失敗する可能性があります。

代わりに、容量値BlockingCollectionを渡すことができるコンストラクターの 1 つで を初期化し、メソッドを使用して実際に何かをコレクションに追加します。コレクションの現在のサイズがこの容量を下回るまで、メソッドはブロックされます。intAdd()Add()

このTryAdd()メソッドは収集容量も考慮していることに注意してください。ただし、完全なコレクションは、追加操作の即時の失敗として扱われます。これは、あなたが望むものとは正反対のようです。つまり、追加操作が確実に成功するまでブロックします。そのために、Add()メソッドは間違いなく使用するものです。

  1. 「空の場合はTryTakeでブロックします」

ブロックを持つことが意味をなさないのと同じ理由で、TryAdd()ブロックを持つことも意味がありませんTryTake()

代わりに、返されたオブジェクトを呼び出しGetConsumingEnumerable()て使用し、コレクションからアイテムを取得します。コレクションが空にIEnumerable<T>.MoveNext()なると、新しいアイテムがコレクションに追加されるか、メソッドが呼び出されるまで、メソッドはブロックされますCompleteAdding()


上記でニーズに対応できない場合は、質問を編集して、達成したいことを正確に説明する必要があります。タイトルで尋ねた質問に対して、誰かが完全で正確な回答をくれたとしても、それは実際に何かを行うコードを書く助けにはなりません。私見ですが、私たちがそれをお手伝いできるように、あなたがやろうとしていることにより集中してください。

于 2015-01-11T22:28:06.923 に答える