Я пытаюсь оптимизировать процедуру, которая выглядит примерно так (упрощенно):
public async Task<IEnumerable<Bar>> GetBars(ObjectId id){
var output = new Collection<Bar>();
var page = 1;
var hasMore = true;
while(hasMore) {
var foos = await client.GetFoos(id, page);
foreach(var foo : foos) {
if(!Proceed(foo)) {
hasMore = false;
break;
}
output.Add(new Bar().Map(foo)
}
page++;
return output;
}
Метод, который вызывает GetBars()
, выглядит примерно так
public async Task<Baz> GetBaz(ObjectId id){
var bars = await qux.GetBars();
if(bars.Any() {
var bazBaseData = qux.GetBazBaseData(id);
var bazAdditionalData = qux.GetBazAdditionalData(id);
return new Baz().Map(await bazBaseData, await bazAdditionalData, bars);
}
}
GetBaz()
возвращает от 0 до большого количества элементов. Поскольку мы проходим через несколько миллионов идентификаторов, мы изначально добавили оператор if(bars.Any())
в качестве начальной попытки ускорить приложение.
Поскольку ожидается GetBars()
, поток блокируется до тех пор, пока он не соберет все свои данные (что может занять некоторое время). Моя идея состояла в том, чтобы использовать yield return, а затем заменить if(bars.Any())
проверкой, которая проверяет, получили ли мы хотя бы один элемент, чтобы мы могли тем временем запустить два других асинхронных метода (что также требует некоторого времени для выполнения).
Тогда мой вопрос, как это сделать. Я знаю, что System.Linq.Count()
и System.Linq.Any()
опровергают всю идею доходности, и если я проверю первый элемент в перечислимом, он будет удален из перечисляемого.
Есть ли другой/лучший вариант, кроме добавления, например, параметра out к GetBars()
?
TL;DR: как проверить, содержит ли перечисляемое из yield return какие-либо объекты, не начиная его итерации?
GetBars()
какие-либо элементы, проверяющие первый элемент. Верно? - person Moti Azu   schedule 10.11.2014await client.GetFoos
самой длинной частью вашегоGetBars
метода? - person Rawling   schedule 10.11.2014GetBars()
. - person Asser   schedule 10.11.2014