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
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();
4条答案
按热度按时间yyhrrdl81#
您可以在
Queue<T>
上创建一个扩展方法:用法:
41zrol4v2#
您可以在.NET中使用Linq通过使用
Enumerable.Range()
方法沿着Select()
扩展方法来实现这一点:var chunk = Enumerable.Range(0, chuckCount).Select(i => queue.Dequeue()).ToList();
它的工作原理是生成一个整数的可枚举对象,然后为新的可枚举对象中的每个整数将一个项目从队列中出队。通过调用
ToList()
确保操作立即完成。jmp7cifd3#
TPL Dataflow库提供了BatchBlock < T >,它将消息的输入序列分组为所需大小的块。
u59ebvdq4#
我可能只使用一个简化的版本来将队列中的内容出队,并使用计时器或您正在使用的系统中可用的任何东西以特定的间隔执行此操作。
因此,10秒后,如果有10个,请出队并处理,或者如果有100个,请执行相同的操作。这完全取决于负载、正在完成的工作等,以及对延迟的预期,以及对您试图实现的目标的响应等。
我假设使用队列不会立即产生结果,而是可以在更长的时间段内执行,比如数据聚合。
这样就没有严格的SLA窗口。可能需要一些基准测试和测试来了解负载情况以及首选的时间间隔。