我有一个包含数千个元素的集合,我做一个for循环来一次处理100个元素然后上传它们并暂停5秒
while (EntriesList.Count > 0)
{
service.InsertEntries(EntriesList.Take(100).ToList<Entry>());
System.Threading.Thread.Sleep(5000);
}
service.InsertEntries
需要List<Entry>
作为参数,还有更好的方法来实现这样的事情吗?
通常情况下,我使用带有%
运算符和临时列表的for循环,上面是否相同?
答案 0 :(得分:3)
这将一次又一次插入前100个条目。
跟踪您的位置,并使用Skip
继续前进:
int current = 0;
int batchSize = 100;
while (current < EntriesList.Count)
{
service.InsertEntries(EntriesList.Skip(current).Take(batchSize).ToList());
current += batchSize;
System.Threading.Thread.Sleep(5000);
}
答案 1 :(得分:2)
EntriesList.Take(100).ToList()将创建一个包含100个条目的新列表,您不会从EntriesList中删除100个条目。
您可以执行以下操作:
List<TYPE> objectsforupload = EntriesList.ToList();
while (objectsforupload.Count > 0)
{
List<TYPE> uploadlist = objectsforupload.Take(100).ToList();
objectsforupload = objectsforupload.Where(x => !uploadlist.Contains(x)).ToList();
service.InsertEntries(objectsforupload);
System.Threading.Thread.Sleep(5000);
}
答案 2 :(得分:2)
在.Take()
EntriesList.RemoveRange(0, Math.Min(EntriesList.Count, 100));
它将删除前100个元素。
编辑:更完整的例子:
while (EntriesList.Count > 0)
{
var poppedEntries = EntriesList.Take(100).ToList<Entry>();
EntriesList.RemoveRange(0, poppedEntries.Count);
service.InsertEntries(poppedEntries);
System.Threading.Thread.Sleep(5000);
}
答案 3 :(得分:2)
对于这种事情,你应该写一个Chunkify
扩展方法。您可以从Marc here获得一个很好的例子。但由于这个问题,它总是返回一个固定大小的数组,也许是空条目。
所以这个实现可能更符合您的要求:
/// <summary>
/// Divides an enumeration into smaller (same-sized) chunks.
/// </summary>
/// <typeparam name="T">The type of the elements within the sequence.</typeparam>
/// <param name="source">The sequence which should be breaked into chunks.</param>
/// <param name="size">The size of each chunk.</param>
/// <returns>An IEnumerable<T> that contains an IEnumerable<T> for each chunk.</returns>
public static IEnumerable<IEnumerable<T>> Chunkify<T>(this IEnumerable<T> source, int size)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
if (size < 1)
{
throw new ArgumentOutOfRangeException("size");
}
return ChunkifyImpl(source, size);
}
private static IEnumerable<IEnumerable<T>> ChunkifyImpl<T>(IEnumerable<T> source, int size)
{
using (var iter = source.GetEnumerator())
{
while (iter.MoveNext())
{
var chunk = new List<T>(size);
chunk.Add(iter.Current);
for (int i = 1; i < size && iter.MoveNext(); i++)
{
chunk.Add(iter.Current);
}
yield return chunk;
}
}
}
现在您可以按如下方式使用此扩展程序:
foreach(var chunk in EntriesList.Chunkify(100))
{
service.InsertEntries(chunk);
Thread.Sleep(5000);
}
答案 4 :(得分:1)
按照目前的情况,你的代码不起作用,你也应该跳过相同的数量和
while (entries.Count > 0)
{
service.InsertEntries(entries.Take(100).ToList<Entry>());
entries = entries.Skip(100);
System.Threading.Thread.Sleep(5000);
}
然而,这表现非常糟糕。 IEnumable&lt;&gt;你从Skip()回来会在每次调用时增加开销。
因此,针对此场景的最佳建议是使用for循环。