Параллельное выполнение простого запроса LINQ
Я все еще очень новичок в LINQ и PLINQ. Я обычно просто использую петли и List.BinarySearch
во многих случаях, но я пытаюсь выйти из этого мышления, где могу.
public class Staff
{
// ...
public bool Matches(string searchString)
{
// ...
}
}
используя "нормальный" LINQ-извините, я не знаком с терминологией - я могу сделать следующее:
var matchedStaff = from s
in allStaff
where s.Matches(searchString)
select s;
но я хотел бы сделать это параллельно:
var matchedStaff = allStaff.AsParallel().Select(s => s.Matches(searchString));
когда я проверяю типа matchedStaff
, список bool
s, чего я не хочу.
прежде всего, что я здесь делаю неправильно, и, во-вторых, как мне вернуть List<Staff>
из этого запроса?
public List<Staff> Search(string searchString)
{
return allStaff.AsParallel().Select(/* something */).AsEnumerable();
}
возвращает IEnumerable<type>
, а не List<type>
.
2 ответов
для первый вопрос, вы должны просто заменить Select
С Where
:
var matchedStaff = allStaff.AsParallel().Where(s => s.Matches(searchString));
Select
является оператором проекции, не фильтрующий, поэтому вы получаете IEnumerable<bool>
соответствует проекции всех ваших объектов персонала из входной последовательности в bools, возвращаемые вашим Matches
вызов метода.
я понимаю, что это может быть интуитивно понятным для вас, чтобы не использовать select
вообще, как кажется, вы больше знаком с "синтаксисом запроса", где ключевое слово select является обязательным, что не относится к использованию" лямбда-синтаксиса "(или" свободного синтаксиса")... независимо от названия), но так оно и есть;)
операторы проекций, такой Select
, принимают за вход элемент из последовательности и преобразуют / проецируют этот элемент как-то на другой тип элемента (здесь проецируют на bool
type). Тогда как операторы фильтрации, такие как Where
, как введите элемент из последовательности и либо вывести элемент как таковой в выходной последовательности или не опережают элемент вообще, на основе предиката.
что касается вашего второй вопрос, AsEnumerable
возвращает IEnumerable
как следует из названия ;)
Если вы хотите получить List<Staff>
можно назвать ToList()
(как следует из названия ;)) :
return allStaff.AsParallel().Select(/* something */).ToList();
надеюсь, что это помогает.
нет необходимости отказываться от обычного синтаксиса LINQ для достижения параллелизма. Вы можете переписать исходный запрос:
var matchedStaff = from s in allStaff
where s.Matches(searchString)
select s;
параллельный LINQ ( "PLINQ") версия будет:
var matchedStaff = from s in allStaff.AsParallel()
where s.Matches(searchString)
select s;
чтобы понять, где bool
s приходят от, когда вы пишете следующее:
var matchedStaff = allStaff.AsParallel().Select(s => s.Matches(searchString));
это эквивалентно следующему синтаксис:
var matchedStaff = from s in allStaff.AsParallel() select s.Matches(searchString);
как заявил Даркей, если вы хотите использовать синтаксис c# вместо синтаксиса запроса следует использовать Where()
:
var matchedStaff = allStaff.AsParallel().Where(s => s.Matches(searchString));