ここでは、TaskFactory
の拡張メソッドを作成する方法があります。
public static class TaskFactoryExtension
{
public static Task StartNew(this TaskFactory target, Action action, int parallelism)
{
var tasks = new Task[parallelism];
for (int i = 0; i < parallelism; i++)
{
tasks[i] = target.StartNew(action);
}
return target.StartNew(() => Task.WaitAll(tasks));
}
}
あなたの呼び出しコードは次のようになります。
ConcurrentQueue<T> queue = GetQueue();
int n = GetDegreeOfParallelism();
var task = Task.Factory.StartNew(
() =>
{
T item;
while (queue.TryDequeue(out item))
{
ProcessItem(item);
}
}, n);
task.Wait(); // Optionally wait for everything to finish.
Parallel.ForEach
を使用する別のアイデアがあります。このアプローチの問題点は、並列度が必ずしも高く評価されない可能性があることです。あなたは、絶対量ではなく、許容される最大量のみを示しています。
ConcurrentQueue<T> queue = GetQueue();
int n = GetDegreeOfParallelism();
Parallel.ForEach(queue, new ParallelOptions { MaxDegreeOfParallelism = n },
(item) =>
{
ProcessItem(item);
});
BlockingCollectionは、キューの目的を無効にします。私はそれが反復されている間、ブロッキングコレクションからアイテムを削除することはできません。 –
[GetConsumingEnumerable](http://msdn.microsoft.com/en-us/library/dd287186.aspx)を使用することはできません。 'foreach(Item item in _collection.GetConsumingEnumerable())'のように、コレクションが空の場合にアイテムが追加されるのを待ってブロックします。 –