2012-12-18 13 views
10

Nadal jestem bardzo nowy dla LINQ i PLINQ. Generalnie używam tylko pętli i List.BinarySearch w wielu przypadkach, ale staram się wyjść z tego nastawienia gdzie mogę.Uruchamianie prostej kwerendy LINQ równolegle

public class Staff 
{ 
    // ... 
    public bool Matches(string searchString) 
    { 
    // ... 
    } 
} 

Korzystanie z "normalnym" LINQ - Przepraszam, jestem zaznajomiony z terminologią - można wykonać następujące czynności:

var matchedStaff = from s 
        in allStaff 
        where s.Matches(searchString) 
       select s; 

Ale chciałbym to zrobić równolegle:

var matchedStaff = allStaff.AsParallel().Select(s => s.Matches(searchString)); 

Kiedy sprawdzam typ matchedStaff, jest to lista bool s, która nie jest tym, czego chcę.

Po pierwsze, co robię źle tutaj, a po drugie, jak mogę zwrócić List<Staff> z tego zapytania?

public List<Staff> Search(string searchString) 
{ 
    return allStaff.AsParallel().Select(/* something */).AsEnumerable(); 
} 

powraca IEnumerable<type> nie List<type>.

+3

Można nadal używać składni kwerendy (tak to się nazywa) z PLINQ: 'z s w allStaff.AsParallel() gdzie s.Matches (searchString) wybierz s'. – svick

Odpowiedz

26

Dla pierwsze pytanie, należy po prostu wymienić Select z Where:

var matchedStaff = allStaff.AsParallel().Where(s => s.Matches(searchString)); 

Select jest operatorem projekcja, a nie filtrowanie jeden, to dlaczego są coraz IEnumerable<bool> odpowiada projekcji wszystkich obiektów Staff z sekwencji wejściowej do wartości bool zwracanych przez wywołanie metody Matches.

Rozumiem, że w ogóle nie można używać select, ponieważ wydaje się, że lepiej znasz "składnię zapytania", gdzie słowo kluczowe jest obowiązkowe, co nie ma miejsca w przypadku "składni lambda" (lub „biegle składnia” ... bez względu na nazewnictwo), ale tak to już jest;)

Rzuty operatorzy, taki Select, przyjmowanych jako wejście element z sekwencji i przekształcenia/projektów jakoś ten element do innego typ elementu (tutaj rzutowany na typ bool). Podczas gdy operatory filtrujące, takie jak Where, pobierają jako dane wejściowe element z sekwencji i albo wyprowadzają element jako taki w sekwencji wyjściowej albo w ogóle nie wyprowadzają elementu na podstawie predykatu.

Jak dla drugie pytanie, AsEnumerable zwracającej IEnumerable jak sama nazwa wskazuje;) Jeśli chcesz uzyskać List<Staff> należy raczej nazwać ToList() (jak sama nazwa wskazuje;)):

return allStaff.AsParallel().Select(/* something */).ToList(); 

Mam nadzieję, że to pomoże.

6

Nie ma potrzeby, aby porzucić normalną składnię LINQ, aby osiągnąć paralelizm.Można przerobić oryginalnego zapytania:

var matchedStaff = from s in allStaff 
    where s.Matches(searchString) 
    select s; 

Równoległe LINQ (“PLINQ”) wersja będzie:

var matchedStaff = from s in allStaff.AsParallel() 
    where s.Matches(searchString) 
    select s; 

Aby zrozumieć, gdzie bool s pochodzą, kiedy piszesz, co następuje:

var matchedStaff = allStaff.AsParallel().Select(s => s.Matches(searchString)); 

Jest to odpowiednik następującej składni zapytania:

var matchedStaff = from s in allStaff.AsParallel() select s.Matches(searchString); 

As stated by darkey, jeśli chcesz korzystać z C# składni zamiast składni zapytań, należy użyć Where():

var matchedStaff = allStaff.AsParallel().Where(s => s.Matches(searchString)); 
Powiązane problemy