3

線程池,我想知道哪些(如果有的話)是使用System.Threading.Task對象排隊的工作項目(委託)的線程池在.NET 4.5的最直接的方法。我想要做的實質是將ThreadPool.QueueUserWorkItem()方法的排隊功能與Task s一起復制。如果我錯了,請糾正我的錯誤,但據我所知,使用此方法排隊的工作項目保證按排入隊列的順序執行(也許我對多處理器方案完全錯誤)。我必須編寫表現相同的代碼,使用Task s。排隊的工作項目使用System.Threading.Task

我工作的便攜式類庫,所以這就是爲什麼我不能用ThreadPool.QueueUserWorkItem(),而是我必須依靠Task S表示這一目標。你會建議什麼技術?默認任務調度程序是否適合此要求?

+0

我開始認爲PCL爲每個平臺本身選擇適當的TaskScheduler。檢查我的答案的編輯,但我將不得不測試更多 –

回答

1

你問什麼是任務已經做了什麼。 Task本質上是一個lambda的包裝器,默認情況下會被排隊等待在ThreadPool上執行。最重要的是,任務添加了延續,異常處理,取消和許多便利功能,使多線程更容易。

如果你不想使用線程池,你可以創建自己的TaskScheduler,並創建一個新的任務時使用它。 TaskScheduler本質上接收一個Task並安排它執行。

默認的TaskScheduler使用ThreadPool.QueueUserWorkItem加上一些盜竊魔法和多個隊列處理。其他實現可以使用優先級隊列,對線程的最大或最小數量或其作者想要使用的任何技術設置自己的限制。

編輯

我沒有注意到便攜式部分從一開始。所以問題是「PCL提供了使用ThreadPool的TaskScheduler還是我必須創建自己的」?

.NET 4+提供了ThreadPoolTask​​Scheduler。不幸的是,這似乎從PCL子集中丟失了。看起來您可能必須創建自己的TaskScheduler或使用Nuget包來添加平臺特定的實現。

不知怎的,我覺得ThreadPoolTask​​Scheduler將是一個不錯的選擇對於一款Windows Phone項目

使用ReSharper的和.NET的調試符號一些diggind之後,我覺得PCL本身找到任何可用平臺的TaskScheduler實現。

在.NET 4.0中,TaskScheduler.Default返回ThreadPoolTask​​Scheduler,一個INTERAL BCL類的一個實例。在PCL子集中,TaskScheduler.Default返回null,ThreadPoolTask​​Scheduler不可用。

爲ThreadPoolTask​​Scheduler的源代碼probalby可從微軟的參考源服務器,但你也可以很快在dotnetframework.org

瀏覽它,我創建了一個返回一個新的任務PCL類,並把它稱爲從.NET 4.5的控制檯應用程序來查看它將使用的TaskScheduler。我發現PCL類實際上使用了ThreadPoolTask​​Scheduler。

我還沒有與Windows 8或Windows Phone 8的項目嘗試這樣呢,雖然我懷疑我會得到每個平臺的默認的TaskScheduler。

+0

事實上,我最終達到了相同的結論,一個自定義的'TaskScheduler'是要走的路,唯一的問題是它有點痛苦由於缺乏'ThreadPool',在便攜式類庫項目中實現一個。我只能通過引用可移植類庫的平臺特定庫的依賴注入來實現。 –

+0

@GabrielS,我很困惑。 'Task.Factory.StartNew(...)'有什麼問題?它被列爲支持便攜式類庫。 –

+0

這是關於調度程序,而不是任務本身。抽象類TaskScheduler可用,但它返回'null'作爲當前和默認實例。具體的ThreadPoolTask​​Scheduler類是大多數平臺默認的,它在便攜庫中是缺少的 –

3

ThreadPool不需要以與預定完全相同的順序執行委託(至少我沒有在文檔中找到任何類似的擔保)。但據我所知,它幾乎是如此表現。

Task s(使用默認的TaskScheduler)更復雜,因爲它們使用線程本地隊列,它們按LIFO順序處理。如果你想確保你所有的Task都進入全局FIFO隊列,你可以使用TaskCreationOptions.PreferFairness。但是,再次,沒有記錄具體做什麼,所以具體可以改變。

+0

注意的一個問題是關於*便攜式*庫,在這裏你甚至可能不會有任何要使用的TaskScheduler的實現。 Gabriel本質上是問「在PCL中是否有使用ThreadPool的TaskScheduler,還是我必須爲每個目標平臺推出我自己的」? –

+1

@PanagiotisKanavos這不是我理解這個問題的方式。它不要求'ThreadPool',它要求以一種先進先出的方式來調度Task。 「PreferFairness」(似乎在PCL中可用)就是這樣做的。 – svick

+0

@svick實際上,我只提到'ThreadPool'作爲一個(可能不是很好)的例子,'Task'的FIFO調度就是我正在尋找的。我會試着看看'PreferFairness'選項是否確實是我的便攜式類庫所針對的多個平臺上默認調度程序的解決方案。 –