在成批转换列表时,yield return跳过已签入if条件但由于大小限制而未添加到bucket的对象。
消息总计数:4
第一个存储区计数:2
第二个存储区计数:1
跳过消息列表中的第三条消息
在这里,我正在创建大小为250kb的存储桶。是否有其他方法保存正确的状态,或者是否需要使用for循环?
public static IEnumerable<IEnumerable<Message>> GetBatchSize(IList<Message> source)
{
List<Message> bucket = null;
long size = 0;
foreach (var item in source)
{
if (bucket == null)
{
bucket = new List<Message>();
}
size = size + item.Size;
if (250 - (size / 1024) >= item.Size / 1024)
{
bucket.Add(item);
continue;
}
yield return bucket;
bucket = new List<Message>();
size = 0;
}
if (bucket?.Count > 0 && size<250)
{
yield return bucket;
}
}
您可以将项目添加到收益返回后新创建的列表中:
foreach (var item in source)
{
// omitted for brevity
yield return bucket;
bucket = new List<Message> { item };
size = item.Size;
}
(假设没有单个消息的大小大于桶大小)
首先,当当前bucket不能包含当前消息时,您应该将消息放入下一个bucket,而不是将其丢弃。因此,在foreach
循环中返回收益率后,您应该执行以下操作:
bucket = new() { item };
^^^^^^^^
此外,您向桶中添加物品的条件不正确。它“双重计算”当前项目的大小。请注意,size
此时已经有了项。大小
已添加到其中!此外,在此处使用除法将丢弃余数,这将导致在以下情况下产生不正确的结果:
GetBatchSize(new List<Message> {
new Message { Size = 250 * 1024 - 1 },
new Message { Size = 1 },
new Message { Size = 1 },
});
与其除法,不如乘:
if (size <= 250 * 1024)
{
bucket.Add(item);
continue;
}
另外,我不确定最后一个大小的目的是什么
if (bucket?.Count > 0)
{
yield return bucket;
}