我有一个名为IEnumerable<IEnumerable<T>>
的{{1}}方法,其工作方式与
Batch
- &GT;
var list = new List<int>() { 1, 2, 4, 8, 10, -4, 3 };
var batches = list.Batch(2);
foreach(var batch in batches)
Console.WriteLine(string.Join(",", batch));
我遇到的问题是我要优化像
这样的东西1,2
4,8
10,-4
3
通过
foreach(var batch in batches)
ExecuteBatch(batch);
或
Task[] tasks = batches.Select(batch => Task.Factory.StartNew(() => ExecuteBatch(batch))).ToArray();
Task.WaitAll(tasks);
(因为Action[] executions = batches.Select(batch => new Action(() => ExecuteBatch(batch))).ToArray();
var options = new ParallelOptions { MaxDegreeOfParallelism = 4 };
Parallel.Invoke(options, executions);
是一个涉及IO的长时间运行的操作
然后我注意到每个ExecuteBatch
被搞砸了,只有一个元素是batch
。知道发生了什么或如何解决它?
批处理:
default(int)
答案 0 :(得分:3)
正如评论中所述,您的实际问题是Batch
。
此代码:
for(var mover = source.GetEnumerator(); ;)
{
if(!mover.MoveNext())
yield break;
yield return LimitMoves(mover, size);
}
当Batch
具体化时,此代码将不断调用MoveNext()
,直到可枚举用尽为止。 LimitMoves()
使用相同的迭代器,并且 lazily 被调用。由于Batch
耗尽了可枚举,LimitMoves()
将永远不会发出项目。 (实际上,它只会发出default(T)
,因为它总是返回mover.Current
,一旦枚举完成,它将是default(T)
。
这是Batch
的实现,它将在实现时(因此并行)时起作用。
public static IEnumerable<IEnumerable<T>> Batch<T>(this IEnumerable<T> source, int size)
{
var mover = source.GetEnumerator();
var currentSet = new List<T>();
while (mover.MoveNext())
{
currentSet.Add(mover.Current);
if (currentSet.Count >= size)
{
yield return currentSet;
currentSet = new List<T>();
}
}
if (currentSet.Count > 0)
yield return currentSet;
}