17

Stephen Toub blogged是什麼的SynchronizationContext和的TaskScheduler

雙方的SynchronizationContext和的TaskScheduler是抽象, 代表「調度」,你給一些工作的東西,它 決定何時何地之間的概念差別運行那項工作。調度器有許多不同的形式。例如,ThreadPool是一個調度程序:調用ThreadPool.QueueUserWorkItem來提供一個委託來運行, 委託隊列,並且一個ThreadPool的線程最終 接收並運行該委託。您的用戶界面還有一個調度程序:消息泵。

所以System.Reactive.Concurrency.EventLoopSchedulerDispatcherThreadPoolTaskSchedulerSyncrhonizationContextIScheduler implementations of Reactive Extensions是在這個意義上所有的 「調度」。

他們有什麼區別?

他們爲什麼都需要?我想我得到EventLoop,Dispatcher,ThreadPool。 IScheduler也很好地解釋。
但是TaskScheduler和SyncrhonizationContext仍然不清楚。

Stephen Cleary's excellent article解釋SyncrhonizationContext,我想我明白了。那麼爲什麼我們需要TaskScheduler,目前還不清楚。

請解釋或指出來源。

+0

可能有很多原因,如答案所示。另一個未提及的我在這個MSDN中發現博客文章: http://blogs.msdn.com/b/pfxteam/archive/2012/01/20/10259082.aspx 它表示,SyncrhonizationContext.Post異步方法不會在工作項執行時提供通知。文章建議如何添加一個使用TaskCompletionSource返回任務的擴展方法 – 2012-03-06 19:37:32

回答

8

每個平臺都有自己的「調度程序」,並且它們都有自己的抽象。例如WinForms使用消息泵。 WPF使用「Dispatcher」中抽象的另一個消息泵。ThreadPool是「ThreadPool」中抽象的另一個「調度程序」。這些(和其他一些)是較低級別的調度程序。

任務和任務調度程序希望任務的用戶不必考慮在這些較低級別調度任務(當然,可以採用抽象的方式)。你應該能夠開始一個任務,並且一個環境「調度程序」應該照顧它。例如,無論我在哪個平臺下運行,TaskFactory.StartNew(()=>{LengthyOperation()})都應該可以工作。這就是SynchronizationContext進來的地方。它知道當前運行的框架涉及哪些底層調度程序。這被傳遞給TaskScheduler,並且該調度程序既可以調度任務(可能在ThreadPool上),也可以通過與當前正在運行的框架相關聯的較低級別調度程序(參見SynchronizationContext)來調度延續以保持同步要求。例如雖然您希望您的任務在ThreadPool中運行,但您可能需要繼續在UI線程中運行。

重要的是要知道TaskScheduler是多個其他調度程序的抽象。這不是它存在的唯一原因,而是這種「額外」抽象的原因之一。「

+0

_SynchronizationContext進來。它知道在當前運行的框架中涉及哪些底層調度器_ - 如果它知道,爲什麼我們需要'TaskScheduler'?例如:_All隊列到WindowsFormsSynchronizationContext的所有委託一次執行一個;它們按照它們排隊的順序由特定的UI線程執行。[Source](https://msdn.microsoft.com/en-us/magazine/gg598924.aspx)如果'SynchronizationContext'可以爲任務執行,那麼我仍然無法看到「TaskScheduler」的需要。 – user4205580 2015-11-17 09:11:41

+0

_傳遞給TaskScheduler_ - **將**傳遞給TaskScheduler? – user4205580 2015-11-17 10:09:13

+0

'TaskScheduler'是抽象的,所以在技術上沒有任何東西被傳遞給它。這是'TaskScheduler'的實現,它接受傳遞給它們的信息。他們需要的功能依賴於每個實現。現在,對於Fx中的兩個'TaskScheduler'實現,您並不是自己創建它們,而是接受其中一個實例的單例。一般來說,你不關心傳遞給它們的內容。也許我已經錯過了你的問題的重點,如果是這樣,請你澄清一下嗎? – 2015-11-17 18:40:40

6

雖然,引,

兩者的SynchronizationContext和的TaskScheduler是抽象, 表示「調度器」

IMO,抽象度(以及因此API)不同。 SynchronizationContext是一個更通用的API,因爲Post/Send接受一個簡單的方法委託。

另一方面,TaskScheduler是特定於TPL的抽象 - 所以它提供了諸如QueueTask之類的方法,它處理Task對象。使用同步上下文而不是任務調度器(即具有TPL特定的SynchronizationContext實現)會使得使用任務調度更加繁瑣(當然,這將是TPL環境中的弱類型API)。因此,TPL設計人員選擇對抽象調度器API進行建模,這對於TPL來說是有意義的(無論如何 - 這是抽象的目的 - 對吧?) - 當然,爲了縮小差距,FCL包含內部類SynchronizationContextTaskScheduler,它是SynchronizationContext的封裝TaskScheduler實現。

SynchronizationContext是在.NET 2.0中引入的,而TPL是在.NET 4中引入的。它有趣的想法是什麼FCL設計者會選擇如果序列是其他方式,即如果TPL在.NET時期存在2.0。 IMO,TaskScheduler可以被用來代替SynchrinizationContext,通過在特定專業化中將分類建模爲任務。

+0

感謝Vinay我還假設其中一個比另一個更新,但仍然讓我感到困惑的是,每個異步庫似乎都堅持要設計自己的抽象,即使它們屬於同一代,看看Rx(Reactive Extensions),這也是NET 4.他們得到了IScheduler和nu大量的實現。與任務無關。這次它不是一個抽象類,而是一個接口。考慮到圖書館的多樣性,每個圖書館都有自己的優勢,但是卻都有很大的重疊,我希望能有一本書或一本整理出來的文章。 – 2012-03-06 19:29:36

+1

@MichaelKariv,AFAIK,Rx不是FCL的一部分 - 它是一個在.NET 4之後開發和發佈的庫。它可能會或可能不會被添加到下一個版本的Fx中。說我相信你會一直看到同一個概念的多個抽象,因爲一個抽象可能不適合所有場景(不是從功能的角度來看,而是接口的角度) – VinayC 2012-03-07 04:17:39

+2

SynchronizationContext更多的是關於執行關係的要求。例如,如果要更新控件,則需要在UI線程上執行該操作。該需求在SychronizationContext中抽象化。單個任務如何相互調度以及它們在哪裏運行(可能需要同步*)被抽象到TaskScheduler中。相關但正交的抽象。 – 2013-04-15 17:17:54

相關問題