2011-11-28 13 views
18

Tôi đã cập nhật mã của mình để sử dụng Tác vụ thay vì chuỗi ....Tôi có nên nhận thấy sự khác biệt trong việc sử dụng Task vs Threads trong .Net 4.0 không?

Nhìn vào mức sử dụng bộ nhớ và CPU Tôi không nhận thấy bất kỳ cải thiện nào trên PC đa lõi, đây có phải là dự kiến ​​không?

Ứng dụng của tôi về cơ bản khởi động đề/nhiệm vụ trong các đối tượng khác nhau khi nó chạy ...

Tất cả tôi đang làm là một đơn giản

Task a = new Task(...) 
a.Start(); 
+4

"Tôi không nhận thấy bất kỳ cải tiến nào" Điều đó sẽ phụ thuộc nhiều vào mã thực tế ... Bạn thậm chí có thể đã thấy sự suy giảm. –

+1

'Nhiệm vụ' không phải là lớp học phép thuật. Cuối cùng, chúng cũng là 'thread', –

+0

Tôi chỉ mặc dù Tasks nhận thức được môi trường đa lõi không giống như các luồng, vì vậy sẽ biết cách phân tán chính xác chúng trên nhiều lõi. Cũng vì họ không cần phải được tạo ra kể từ khi họ sử dụng ThreadPool họ sẽ có nhiều bộ nhớ hiệu quả. – TheWommies

Trả lời

28

Có những tác động khác nhau để sử dụng Công việc thay vì Chủ đề , nhưng hiệu suất không phải là một trong những chủ đề lớn (giả sử bạn không tạo ra số lượng lớn các chủ đề.) Một vài khác biệt chính:

  1. TaskScheduler mặc định sẽ sử dụng phân luồng, vì vậy một số Ta sks có thể không bắt đầu cho đến khi các nhiệm vụ đang chờ xử lý khác đã hoàn thành. Nếu bạn sử dụng Thread trực tiếp, mọi lần sử dụng sẽ bắt đầu một Thread mới.
  2. Khi trường hợp ngoại lệ xảy ra trong một nhiệm vụ, nó được bao bọc trong một ngoại lệ mà mã gọi có thể nhận được khi nó đợi nhiệm vụ hoàn thành hoặc nếu bạn đăng ký tiếp tục trên nhiệm vụ. Điều này là do bạn cũng có thể làm những việc như chờ đợi trên nhiều Tác vụ để hoàn thành, trong trường hợp đó nhiều ngoại lệ có thể được ném và tổng hợp.
  3. Nếu bạn không quan sát một ngoại lệ không được giải quyết bởi một tác vụ, nó sẽ (tốt, có thể) cuối cùng được ném bởi người hoàn thành nhiệm vụ, điều đặc biệt khó chịu. Tôi luôn khuyên bạn nên gắn kết sự kiện TaskScheduler.UnobservedTaskException để ít nhất bạn có thể ghi lại các lỗi này trước khi ứng dụng thổi lên. Điều này khác với các ngoại lệ của Thread, xuất hiện trong sự kiện AppDomain.UnhandledException.
+0

tóm tắt hữu ích, cảm ơn bạn! –

+0

Cảm ơn, đó là một cái nhìn tổng quan tốt đẹp. Tôi đang nghiên cứu điểm đầu tiên ngay bây giờ, có vẻ thú vị khi sử dụng TaskScheduler. – Kosko

+1

@Kosko, một trong những cách sử dụng phổ biến của TaskScheduler là [TaskScheduler.FromCurrentSynchronizationContext] (http://msdn.microsoft.com/en-us/library/system.threading.tasks.taskscheduler.fromcurrentsynchronizationcontext.aspx), trong đó lên lịch các tác vụ cho một bối cảnh đồng bộ hóa (thường là chuỗi giao diện người dùng). Điều này thường được sử dụng nhất khi đăng ký các lần tiếp tục trên một Tác vụ, do đó việc tiếp tục chạy trong luồng giao diện người dùng thay vì trên nhóm luồng. Nó có thể giúp tránh được nhiều mã Invoke xấu xí trong các phương thức cập nhật giao diện người dùng của bạn. –

3

Một cải tiến tuyệt vời của Takss so với Chủ đề là bạn có thể xây dựng các chuỗi nhiệm vụ một cách dễ dàng. Bạn có thể chỉ định khi nào một tác vụ sẽ bắt đầu sau nhiệm vụ trước đó ("OnSuccess", "OnError", a.s.o.) và bạn có thể chỉ định nếu có một chuyển đổi ngữ cảnh đồng bộ hóa. Điều đó mang lại cho bạn cơ hội tuyệt vời để chạy một tác vụ chạy dài trong bakcground và sau đó một nhiệm vụ giới thiệu giao diện người dùng trên luồng giao diện người dùng.

8

Nếu bạn chỉ đơn giản thay thế mọi cách sử dụng Thread bằng Task và không có thay đổi nào khác, tôi mong đợi hầu như cùng một hiệu suất. API Task thực sự chỉ là, đó là một API trên một tập hợp các cấu trúc hiện có. Dưới mui xe nó sử dụng các chủ đề để sắp xếp các hoạt động của nó và do đó có các đặc tính hiệu suất tương tự.

gì tuyệt vời về Task là những điều mới bạn có thể làm với họ

  • Thành phần với ContinueWith
  • Hủy
  • tầng nấc
  • Etc ...
+2

TPL được loại bỏ mã blof. Đây là API mà mọi nhà phát triển đều muốn viết nhưng không phải dành thời gian để làm như vậy. – Gusdor

0

Nếu bạn là sử dụng .Net 4.0 thì bạn có thể sử dụng Parallel.Gọi phương pháp như vậy

Parallel.Invoke(()=> { 
    // What ever code you add here will get threaded. 
}); 

để biết thêm thấy http://msdn.microsoft.com/en-us/library/dd992634.aspx

+1

Vì vậy, cái gì? Bạn đã đọc câu hỏi chưa? 'Nhìn vào sử dụng bộ nhớ và CPU tôi không nhận thấy bất kỳ cải tiến trên máy tính đa lõi, điều này dự kiến? ' –

+0

nó là sự hiểu biết của tôi rằng Parallel.Invoke có sử dụng đa lõi tốt hơn. Bây giờ tôi có thể sai về điều đó và nếu vậy hãy giáo dục tôi. –

+0

1) Có lẽ, 'Parallel.Invoke' được triển khai với' Tasks'? 2) Câu trả lời cho 'Đây có phải là mong đợi?' –

0

Bạn sẽ thấy sự khác biệt nếu bạn mã ban đầu hoặc chuyển đổi không utlize CPU hoàn toàn. I E. nếu mã ban đầu luôn giới hạn số lượng luồng đến 2, trên máy lõi tứ, nó sẽ chạy ở mức tải khoảng 50% với chuỗi được tạo theo cách thủ công và có khả năng tải 100% với các tác vụ (nếu nhiệm vụ của bạn có thể được kích hoạt ngang hàng). Vì vậy, có vẻ như hoặc mã ban đầu của bạn là hợp lý từ quan điểm hiệu suất của xem, hoặc cả hai implemetaion bị vấn đề hiển thị underutiliztion của CPU.

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