假设有一个函数返回一个延迟枚举的对象:
struct AnimalCount
{
int Chickens;
int Goats;
}
IEnumerable<AnimalCount> FarmsInEachPen()
{
....
yield new AnimalCount(x, y);
....
}
您还有两个函数,它们使用两个单独的
IEnumerable
s,例如:ConsumeChicken(IEnumerable<int>);
ConsumeGoat(IEnumerable<int>);
如何调用
ConsumeChicken
和ConsumeGoat
而不事先a)转换FarmsInEachPen()
tolist(),因为它可能有两个无数的记录,b)没有多线程。基本上:
ConsumeChicken(FarmsInEachPen().Select(x => x.Chickens));
ConsumeGoats(FarmsInEachPen().Select(x => x.Goats));
但没有强制双重枚举。
我可以用多线程来解决这个问题,但是对于每个列表使用一个缓冲队列会变得不必要的复杂。
因此,我正在寻找一种方法,将
AnimalCount
枚举数拆分为两个int
枚举数,而不完全计算AnimalCount
。在锁定步骤中同时运行ConsumeGoat
和ConsumeChicken
没有问题。我能感觉到解决办法不在我掌握之中,但我还不完全在那里。我正沿着一个helper函数的思路思考,这个函数返回一个
IEnumerable
被输入到ConsumeChicken
中,每次使用迭代器时,它都会在内部调用ConsumeGoat
,从而在lock步骤中执行这两个函数。当然,除了,我不想给ConsumeGoat
打不止一次电话。 最佳答案
我不认为有什么方法可以满足您的要求,因为ConsumeChickens(IEnumerable<int>)
和ConsumeGoats(IEnumerable<int>)
是按顺序调用的,它们分别枚举一个列表—如果没有列表的两个单独枚举,您希望如何工作?
根据具体情况,更好的解决方案是使用ConsumeChicken(int)
和ConsumeGoat(int)
方法(每个方法使用一个项),并交替调用它们。这样地:
foreach(var animal in animals)
{
ConsomeChicken(animal.Chickens);
ConsomeGoat(animal.Goats);
}
这将只枚举一次
animals
集合。另外,需要注意的是:根据你的linq提供者以及你到底想做什么,可能会有更好的选择。例如,如果试图使用linq to sql或linq to entities从数据库中获取鸡和羊的总数,则执行以下查询。
from a in animals
group a by 0 into g
select new
{
TotalChickens = g.Sum(x => x.Chickens),
TotalGoats = g.Sum(x => x.Goats)
}
将生成一个查询,并在数据库端执行求和,这比在客户端拉取整个表并执行求和要好得多。