17

Stephen Toub blogged rằngsự khác biệt về khái niệm giữa SynchronizationContext và TaskScheduler

Cả SynchronizationContext và TaskScheduler là trừu tượng mà đại diện cho một “lịch trình”, một cái gì đó mà bạn cung cấp cho một số công việc, và nó xác định khi nào và ở đâu là gì chạy công việc đó. Có nhiều hình thức khác nhau của các bộ lập lịch biểu. Ví dụ, ThreadPool là một scheduler: bạn gọi ThreadPool.QueueUserWorkItem để cung cấp cho một đại biểu để chạy, rằng đại biểu được xếp hàng đợi, và một trong các chủ đề của ThreadPool cuối cùng chọn và chạy đại biểu đó. Giao diện người dùng của bạn cũng có một bộ lập lịch : bơm thông báo.

Vì vậy System.Reactive.Concurrency.EventLoopScheduler, Dispatcher, ThreadPool, TaskScheduler, SyncrhonizationContext, và IScheduler implementations of Reactive Extensions là tất cả "schedulers" trong ý nghĩa đó.

Sự khác nhau giữa chúng là gì?

Tại sao tất cả đều cần thiết? Tôi nghĩ rằng tôi nhận EventLoop, Dispatcher, ThreadPool. IScheduler cũng được giải thích.
Nhưng TaskScheduler và SyncrhonizationContext vẫn chưa rõ ràng với tôi.

Stephen Cleary's excellent article giải thích SyncrhonizationContext, và tôi nghĩ mình đã hiểu. Tại sao chúng ta cần TaskScheduler, không rõ ràng.

Vui lòng giải thích hoặc trỏ đến nguồn.

+0

Có thể có một số lý do, như câu trả lời gợi ý. Một khác chưa được đề cập đến mà tôi tìm thấy trong MSDN này Bài viết blog: http://blogs.msdn.com/b/pfxteam/archive/2012/01/20/10259082.aspx Nó nói rằng SyncrhonizationContext.Post asyncronous phương pháp không cung cấp thông báo khi mục công việc được thực hiện. Bài viết gợi ý cách thêm một phương thức mở rộng sử dụng TaskCompletionSource để trả lại một tác vụ –

Trả lời

8

Mỗi nền tảng có "bộ lập lịch biểu" riêng và chúng có phần trừu tượng riêng của chúng xung quanh. ví dụ. WinForms sử dụng một máy bơm tin nhắn. WPF sử dụng một máy bơm tin nhắn trừu tượng trong "Dispatcher".Một ThreadPool là một "scheduler" trừu tượng trong "ThreadPool". Những (và một số khác) là các trình lên lịch cấp thấp hơn.

Nhiệm vụ và TaskScheduler muốn người dùng Tác vụ không phải suy nghĩ về việc lập kế hoạch nhiệm vụ ở các cấp thấp hơn này (bạn có thể tất nhiên, theo cách trừu tượng). Bạn sẽ có thể bắt đầu một nhiệm vụ và một "bộ lập lịch" xung quanh nên chăm sóc nó. Ví dụ: TaskFactory.StartNew(()=>{LengthyOperation()}) sẽ hoạt động bất kể nền tảng nào tôi đang chạy. Đó là nơi một số SynchronizationContext xuất hiện. Nó biết về những gì mà các trình lên lịch cấp thấp hơn có liên quan đến khung công tác hiện đang chạy. Điều đó được chuyển đến một số TaskScheduler và lịch biểu đó có thể lên lịch các nhiệm vụ (có thể trên ThreadPool) và lên lịch tiếp tục thông qua bộ lập lịch mức thấp hơn được kết hợp với khung hiện đang chạy (xem SynchronizationContext) để duy trì các yêu cầu đồng bộ hóa. ví dụ. mặc dù bạn muốn Nhiệm vụ của mình chạy trong ThreadPool, bạn có thể muốn tiếp tục chạy trong chuỗi giao diện người dùng.

Điều quan trọng cần biết là TaskScheduler là sự trừu tượng hóa của nhiều trình lập lịch khác. Đây không phải là lý do duy nhất nó tồn tại, nhưng một trong những lý do cho sự trừu tượng "thêm" này ".

+0

_SynchronizationContext đi vào. Nó biết về những gì cấp thấp hơn schedulers được tham gia vào các hiện đang chạy framework_ - nếu nó biết rằng, tại sao chúng ta cần 'TaskScheduler'? Ví dụ: _ Tất cả các đại biểu được xếp hàng đợi tới WindowsFormsSynchronizationContext được thực hiện cùng một lúc; chúng được thực thi bởi một chuỗi giao diện người dùng cụ thể theo thứ tự chúng được xếp hàng đợi. [[Nguồn] (https://msdn.microsoft.com/en-us/magazine/gg598924.aspx) Nếu một 'SynchronizationContext' có thể lên lịch các tác vụ cho thực hiện, sau đó tôi vẫn không thể thấy sự cần thiết của 'TaskScheduler'. – user4205580

+0

_Đó được chuyển đến một TaskScheduler_ - ** cái gì ** được chuyển tới 'TaskScheduler'? – user4205580

+0

'TaskScheduler' là trừu tượng, vì vậy về mặt kỹ thuật không có gì được truyền cho nó. Đó là việc triển khai 'TaskScheduler' sẽ chấp nhận thông tin được truyền cho họ. Những gì họ cần để hoạt động là phụ thuộc vào từng thực hiện mặc dù.Đối với hai triển khai 'TaskScheduler' trong Fx bây giờ, bạn không tự tạo chúng, bạn chấp nhận một singleton của một trong số chúng. Nói chung bạn không quan tâm những gì được truyền cho chúng. Có lẽ tôi đã bỏ lỡ điểm của câu hỏi của bạn mặc dù; nếu có, bạn có thể làm rõ? –

6

Mặc dù, như trích dẫn,

Cả SynchronizationContext và TaskScheduler là trừu tượng mà đại diện cho một “lịch trình”

IMO, mức độ trừu tượng (và do đó API) khác. SynchronizationContext là một API tổng quát hơn theo nghĩa là Post/Send có một phương thức delegate đơn giản.

Mặt khác, TaskScheduler là một trừu tượng dành riêng cho TPL - do đó, nó cung cấp các phương thức như QueueTask giao dịch với đối tượng Task. Sử dụng bối cảnh đồng bộ hóa thay vì task scheduler (tức là có một thực thi TPL cụ thể của SynchronizationContext) sẽ làm cho nó tẻ nhạt hơn khi làm việc với task scheduling (và dĩ nhiên, nó sẽ là một API được đánh máy yếu trong ngữ cảnh TPL). Vì vậy, các nhà thiết kế TPL đã chọn để mô hình hóa một API lập lịch trừu tượng có ý nghĩa cho TPL (đó là mục đích trừu tượng - phải không?) - tất nhiên, để thu hẹp khoảng cách, FCL chứa một lớp nội bộ SynchronizationContextTaskScheduler đó là trình bao bọc TaskScheduler trên SynchronizationContext.

Đồng bộ hóa Nội dung được giới thiệu trong .NET 2.0 trong khi TPL được giới thiệu trong .NET 4. Thật thú vị khi nghĩ rằng những gì nhà thiết kế FCL đã chọn nếu trình tự theo cách khác vòng tức là nếu TPL đã tồn tại tại thời điểm .NET. 2.0. IMO, TaskScheduler có thể đã được sử dụng thay vì SynchrinizationContext bằng cách mô hình hóa delgates như là nhiệm vụ trong chuyên môn cụ thể.

+0

Cảm ơn Vinay. Tôi cũng giả định rằng một trong những mô phỏng mới hơn, cái còn lại. mặc dù chúng thuộc về cùng một thế hệ Nhìn vào Rx (Reactive Extensions), cũng là NET 4. Chúng có IScheduler và một nu mber của việc triển khai. Không có gì để làm với Task. Và lần này nó không phải là một lớp trừu tượng mà là một giao diện. Với sự đa dạng của các thư viện, mỗi thư viện có những điểm mạnh riêng, nhưng cực kỳ chồng chéo không kém, tôi ước rằng sẽ có một cuốn sách, hoặc một bài viết phân loại tất cả. –

+1

@MichaelKariv, AFAIK, Rx không phải là một phần của FCL - một thư viện được phát triển và phát hành sau .NET 4. Có thể hoặc không thể thêm vào phiên bản tiếp theo của Fx. Nói rằng, tôi tin rằng bạn sẽ tiếp tục nhìn thấy nhiều trừu tượng của cùng một khái niệm đơn giản bởi vì một trừu tượng có thể không * phù hợp * rất độc đáo với tất cả các kịch bản (đồ đạc không từ quan điểm chức năng mà là quan điểm giao diện) – VinayC

+2

Đồng bộ hóaThông tin thêm về yêu cầu về mối quan hệ thực thi. Ví dụ, nếu bạn muốn cập nhật một điều khiển, bạn cần thực hiện điều đó trên một chuỗi giao diện người dùng. Yêu cầu đó được tóm tắt trong một SychronizationContext. Các nhiệm vụ cá nhân được lên kế hoạch liên quan đến nhau như thế nào và chúng được chạy ở đâu (cần có sự đồng bộ hóa * có thể *) được trừu tượng trong một TaskScheduler. Liên quan, nhưng trừu tượng trực giao. –

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