2012-12-18 47 views
10

Tôi vẫn còn rất mới đối với LINQ và PLINQ. Tôi thường chỉ sử dụng vòng lặp và List.BinarySearch trong nhiều trường hợp, nhưng tôi đang cố thoát ra khỏi suy nghĩ đó, nơi tôi có thể.Chạy một truy vấn LINQ đơn giản song song

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

Sử dụng "bình thường" LINQ - xin lỗi, tôi không quen với các thuật ngữ - Tôi có thể làm như sau:

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

Nhưng tôi muốn làm điều này trong song song:

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

Khi tôi kiểm tra loại matchedStaff, đó là danh sách bool s, không phải là thứ tôi muốn.

Trước hết, tôi đang làm gì sai ở đây và thứ hai, làm cách nào để trả lại một List<Staff> từ truy vấn này?

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

trả về IEnumerable<type>, không List<type>.

+3

Bạn vẫn có thể sử dụng cú pháp truy vấn (đó là những gì nó được gọi là) với PLINQ: 'từ s trong allStaff.AsParallel() trong đó s.Matches (searchString) chọn s'. – svick

Trả lời

26

Đối câu hỏi đầu tiên của bạn, bạn chỉ nên thay thế Select với Where:

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

Select là một nhà điều hành dự, không phải là một bộ lọc một, đó là lý do tại sao bạn đang nhận được một IEnumerable<bool> tương ứng với dự báo của tất cả các đối tượng Nhân viên của bạn từ chuỗi đầu vào đến các công cụ được trả lại bằng lệnh gọi phương thức Matches của bạn.

Tôi hiểu nó có thể phản trực giác để bạn không sử dụng select vì có vẻ như bạn quen thuộc hơn với "cú pháp truy vấn" trong đó chọn từ khóa bắt buộc không phải là trường hợp sử dụng "cú pháp lambda" (hoặc "cú pháp thông thạo" ... bất cứ điều gì việc đặt tên), nhưng đó là cách nó là;)

Dự khai thác, chẳng hạn một Select, đang dùng như đầu vào một phần tử từ chuỗi và biến/dự án thành phần này bằng cách nào đó khác loại phần tử (ở đây chiếu lên loại bool). Trong khi đó, các toán tử lọc, chẳng hạn như Where, đang lấy đầu vào một phần tử từ chuỗi và xuất phần tử như vậy trong chuỗi đầu ra hoặc không xuất ra phần tử nào, dựa trên vị từ.

Đối với bạn câu hỏi thứ hai, AsEnumerable trả về một IEnumerable như tên của nó chỉ ra;) Nếu bạn muốn có được một List<Staff> bạn chứ không nên gọi ToList() (như tên của nó chỉ ra;)):

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

Hy vọng điều này sẽ giúp.

6

Không cần bỏ qua cú pháp LINQ bình thường để đạt được tính song song.Bạn có thể viết lại truy vấn ban đầu của bạn:

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

Các LINQ song song (“PLINQ”) phiên bản sẽ là:

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

Để hiểu nơi bool s đến từ, khi bạn viết như sau:

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

Điều đó tương đương với cú pháp truy vấn sau:

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

As stated by darkey, nếu bạn muốn sử dụng C# cú pháp thay vì cú pháp truy vấn, bạn nên sử dụng Where():

var matchedStaff = allStaff.AsParallel().Where(s => s.Matches(searchString)); 
Các vấn đề liên quan