2015-11-05 3 views
5

かなり一般的なシナリオは、一度にN個処理されるべきアイテムのキューを持つことです。私はいくつかの方法variatyでこの問題を解決することができ一度に複数の項目をデキューできる.NETキュークラスはありますか?

Process batch of 10 
Process batch of 10 
Process batch of 3 

:我々は23 itemsを持っており、一度に10を処理する必要がある場合のように例えば

は...、それは次のようになります。私の質問です:.NET Frameworkは、このシナリオに対処するために特別に設計されたクラスを提供していますか? Queueクラスは完璧ですが、複数のアイテムを一度にデキューすることはできません。

+2

はあなただけで10の項目をデキューすることはできませんループして処理しますか?私はこのアプローチを妨げるあなたの質問から何かを逃していますか? – xxbbcc

+1

なぜ10の完全なバッチをエンキューしないのですか? – Carsten

+0

ええ、私はそれをやりたいとは思っていませんでしたが、実際にはそう多くの理由はありません。それはちょうど醜いです。しかし、ええ、私はおそらくそれを行う必要があります。 –

答えて

10

あなたはQueue<T>に拡張メソッドを作成することができます。

public static class QueueExtensions 
{ 
    public static IEnumerable<T> DequeueChunk<T>(this Queue<T> queue, int chunkSize) 
    { 
     for (int i = 0; i < chunkSize && queue.Count > 0; i++) 
     { 
      yield return queue.Dequeue(); 
     } 
    } 
} 

使用法:

var q = new Queue<char>(); 
q.DequeueChunk(10) // first 10 items 
q.DequeueChunk(10) // next 10 items 

例:https://dotnetfiddle.net/OTcIZX

+0

+1、あなたの答えをありがとう。私はこれが一番きれいだと信じています。私は質問に組み込みのもの(拡張ライブラリーだがイベント)を記述したので、もう一方を受け入れた。再度、感謝します。 –

+1

確かに、他の誰にとっても便利な場合に備えて実装を追加すると思っていました –

1

TPLデータフローライブラリは、メッセージの入力シーケンスを希望のサイズのチャンクにグループ化することを提供します(BatchBlock < T >)。

var bb = new BatchBlock<int>(10); 
var ab = new ActionBlock<int[]>((Action<int[]>)chunk=>HandleChunk(chunk)); 

bb.LinkTo(ab, new DataflowLinkOptions(){PropogateCompletion = true}); 

for(int i = 0; i < 23; ++i) 
{ 
    bb.Post(i); 
} 

bb.Complete(); 
ab.Completion.Wait(); 
+0

ありがとう。ちょうど私は明確です:処理するデータを割り当てるバッチブロック(BatchBlock)に 'Post'します。ただし、一度に処理できるのは10個だけです。おそらく 'Post'はitemのいくつかが返るまでqueスレッドをブロックします。右?それとも並行ですか?それはTPLライブラリのものだからおそらく平行です。 –

+0

@andrerpenaそれは正しいです。デフォルトでは、ActionBlockはメッセージを順番に処理します。オプションでMaxDegreeOfParalIelismを指定すると、この動作を変更できます。 – alexm

+0

を参照してください。ありがとう。ですから、 'chunk => HandleChunck(チャンク)'というアクションが10個のアイテムごとに実行されると仮定します(チャンクは10個のアイテムになります)。しかし、たとえ30に達していなくても最後の3つを処理する必要があることをどのように知っていますか?それは完全な方法のためですか?完了が呼び出されたときにだけプロセスが開始されますか? –

関連する問題