查询的结果不能多​​次枚举

时间:2013-06-08 22:46:11

标签: c# task-parallel-library async-await

我在这个帖子中有一个关于Parelle和Task的问题。 Previous Question Related to this one

我试图做的是通过一个sproc迭代从实体框架返回的集合。

所有查询都完美地在第一个循环中,但在第二个循环时,当我尝试跳过上一个查询结果时,我得到一个查询的结果不能多​​次枚举错误。 < / p>

我意识到调试器告诉我我不能以这种方式分页这个集合。

如何使用.Skip()而不是出错?我需要能够遍历整个集合,直到结束。

这样做有什么神奇之处?

就像我提到的,我可以循环一次,但之后我就会收到错误。

HELP!

ObjectResult<Guid?> memIDs = await Task.Run(() => db.proc_GetCollaborator_UserIDs(projectID));
if (memIDs != null)
{
    while (true)
    {
        var t = memIDs.Take(Environment.ProcessorCount)
                      .Select(id => Task.Run(() => projCollabors.Add(new Collaborator(id.Value, projectID))))
                      .Skip(skip)
                      .ToArray();
        if (t.Length == 0) { break; };
        skip += Environment.ProcessorCount;

        await Task.WhenAll(t);
    };
};

1 个答案:

答案 0 :(得分:3)

您的查询memIDs.Take(Environment.ProcessorCount)始终会从Environment.ProcessorCount获取第一个memIDs项。

下次你打电话给.Take时,它“不记得”你带了一定数量的物品 - 它总是从头开始。

因为您在循环中调用它,所以memIDs被重复枚举。我在想这就是错误的来源。

您可以通过将其转换为如此列表来解决此问题:

var memIDsList = memIDs.ToList();

然后使用memIDsList代替memIDs

但是,这对您的错误查询逻辑没有帮助。我假设你一次尝试N个项目并用它们做点什么?

如果是,您可以使用MoreLinq's Batch扩展名。 (有关Batch的更多信息,请参阅Create batches in linq。)

我不知道使用Batch是否会避免使用.ToList(),但您应该在没有{。}}的情况下进行尝试。