2010-09-14 52 views
5

Hiện tại tôi có một phần mã cần thực hiện khoảng 7 cuộc gọi dịch vụ web cho các nhà cung cấp khác nhau cho dữ liệu. Mỗi cuộc gọi mất một vài giây để thực hiện, vì vậy tôi muốn chạy chúng song song để tăng tốc độ.Sử dụng .Net Parallel Extensions (Parallel.Invoke) cho nhiều cuộc gọi không đồng bộ?

Tôi đã bao gồm 7 cuộc gọi của mình trong Parallel.Invoke hoạt động tốt khi chạy một vài thứ cùng một lúc, nhưng trên máy chủ 2 lõi, nó sẽ chỉ thực thi 2 lần, mỗi lần một lõi. Vì tất cả những gì tôi đang làm là chờ đợi xung quanh cho các cuộc gọi dịch vụ web để trả lại, tôi muốn nó tìm nạp tất cả 7 và đợi họ quay trở lại.

Không có cách nào để thực hiện việc này? Hoặc có lẽ cách tiếp cận của tôi là sai? Có lẽ tôi cần tạo các cuộc gọi không đồng bộ tới các dịch vụ web? Nhưng sau đó làm thế nào để chờ đợi cho họ tất cả trở lại trước khi tiếp tục?

Trả lời

5

nhưng trên một máy chủ 2 lõi, nó sẽ chỉ thực hiện 2 tại một thời điểm, mỗi lõi

tôi sẽ chất vấn này - Parallel.Invoke thường sẽ chạy nhiều nhiệm vụ hơn lõi trong hệ thống của bạn .

Điều đó đang được nói, nếu bạn đang sử dụng lời gọi phương thức không đồng bộ, tôi khuyên bạn nên sử dụng Task.Factory.FromAsync(...) để tạo bảy nhiệm vụ riêng biệt.

Điều này mang lại sự linh hoạt khi thực hiện công việc khác trong khi thực hiện các tác vụ, sau đó gọi Task.WaitAll (hoặc Task.WaitAny) khi bạn quyết định sử dụng kết quả.

Parallel.Invoke, mặt khác, sẽ luôn chặn cho đến khi tất cả bảy hoàn tất.

+2

Tôi có ấn tượng rằng anh ấy muốn tất cả chúng hoàn thành trước khi tiếp tục. –

+1

@Steven: Anh ấy có thể làm gì thông qua Task.WaitAll - nhưng anh ấy có thể thực hiện công việc khác trong khi chờ đợi, nếu có, nếu đó là một tùy chọn. Các trường hợp như thế này, tuy nhiên, thường làm việc với Task.WaitAny, vì bạn thường có thể bắt đầu một số công việc ngay sau khi một số công việc hoàn thành - hiếm khi bạn cần 7 kết quả khác nhau để thực hiện bất kỳ việc xử lý nào ... –

+0

Bạn đang đúng, điều này cũng sẽ hiệu quả và linh hoạt hơn những gì tôi đề xuất. –

0

Bạn có thể chỉ định ParallelOptions để tăng mức độ tương tranh. Mặc định là hợp lý đối với các nhiệm vụ ràng buộc CPU, nhưng bạn đang xử lý các nhiệm vụ I/O-ràng buộc, do đó, nó có ý nghĩa để ghi đè hành vi đó.

+0

Tôi nghĩ rằng việc tăng mức độ tương tranh chỉ đi xa như đồng thời tối đa được phép? tức là nếu bạn có 8 lõi, bạn có thể thiết lập mức độ đồng thời cho bất cứ điều gì .. nhưng sẽ cao hơn 8 sẽ không làm bất cứ điều gì ... – puffpio

+0

@puffpio: Tất cả những gì nó nói là: "MaxDegreeOfParallelism giới hạn số lượng hoạt động đồng thời được thực hiện bởi các cuộc gọi phương thức song song được chuyển thể hiện ParallelOptions này tới giá trị đã đặt, nếu nó là dương. được đặt vào số lượng hoạt động đồng thời chạy. " –

+0

Điều đó làm tôi bối rối, vì nó nói "giới hạn" với tôi nghĩa là nó sẽ không vượt quá số lõi bạn có. Tôi nói rằng vì trang trên Parallel.Invoke nói: "Lưu ý rằng với Invoke(), bạn chỉ cần thể hiện hành động nào bạn muốn chạy đồng thời và thời gian chạy xử lý tất cả các chi tiết lập lịch trình chuỗi, bao gồm tự động chia tỷ lệ cho số lõi trên máy chủ. " – puffpio

1

Không cần thiết phải sử dụng Parallel.Invoke cho việc này. Bạn có thể tiếp tục và đưa ra nhiều yêu cầu không đồng bộ (ví dụ: HttpWebRequest.BeginGetResponse()). Để được thông báo khi họ hoàn tất, bạn có một số tùy chọn. Một cách đơn giản là khởi tạo CountdownEvent trước khi bạn đưa ra yêu cầu đầu tiên và sau đó đợi chủ đề chính trên sự kiện đó sau khi nó đã đưa ra các yêu cầu. Các phương thức gọi lại không đồng bộ đều báo hiệu sự kiện đó khi chúng hoàn thành. Bằng cách đó, bạn đảm bảo rằng tất cả các yêu cầu đã hoàn thành trước khi chủ đề chính của bạn tiếp tục.

+1

Nhưng TPL quá nhiều so với APM. Sẽ tốt hơn nếu chúng ta có thể có cả hai thế giới tốt nhất. –

+0

Sử dụng Task.Factory.StartAsync cung cấp tốt nhất của cả hai thế giới ... mà không cần theo dõi với CountdownEvent, v.v. –

+0

Tôi cần xem xét kỹ hơn TPL. –

0

Tôi sẽ sao chép a response that I made to another question nguyên văn vì nó giống nhau, nếu không nhiều hơn, được áp dụng tại đây.


Bạn chỉ đơn giản là không thể đánh bại Mô hình lập trình không đồng bộ (APM) khi nói đến hiệu năng I/O. Bất cứ lúc nào bạn có thể sử dụng nó, bạn nên. May mắn là thư viện tác vụ song song (TPL) đi kèm với sự hỗ trợ để kết hợp công việc APM với sự kết hợp với các nhiệm vụ TPL "thuần" qua the FromAsync factory method.

Kiểm tra phần này của .NET SDK trên MSDN có tên TPL and Traditional .NET Asynchronous Programming để biết thêm thông tin về cách kết hợp hai mô hình lập trình này để đạt được niết bàn không đồng bộ.

Các vấn đề liên quan