2013-03-11 70 views
5

當我創建一個任務,如何在C#中獲取TPL任務線程的引用?

Task task = Task.Factory.StartNew(() => someMethod(args)); 
在C#4.0 +

,我怎麼能得到這個任務的線程(S)的參考?

是否有可能在創建任務的同一個線程中執行該任務或產生多個線程?

更新:
的原因是:

  • 我想,以確定任務的線程調試器(和它的屬性的名稱)等

創建任務執行總是與創建任務的線程分離?
它是一個,零個還是多個線程?
它在同一個核心上執行嗎?
知道,因爲,例如,我可以把睡在主線程的思想,我凍結了後臺工作是很重要的

更新:
有用的答案:

+5

你不應該需要做的風險。你想解決什麼問題? – SLaks 2013-03-11 14:07:36

+1

據我所知,你不能那樣做。不能保證任務會產生一個新的線程,它可以運行在它創建的同一個線程上。此外,任務(可能)可以在多個線程之間分割。但是我在這裏和@SLaks在一起,關於這種方法有些問題。 – 2013-03-11 14:08:32

+0

答案:(1)肯定,但爲什麼,(2)是,(3)是。 – user7116 2013-03-11 14:08:45

回答

7

創建的任務總是在創建任務的獨立線程中執行嗎?

不,有某些情況下在其中TPL能夠確定該任務可以創建它的同一線程上執行,或者是因爲相關的任務創建選項(或任務調度程序)時,供給或作爲優化,因爲調用線程否則不會有任何事情要做。儘管如此,你並不需要擔心。這不像你最終會阻止UI線程,因爲TPL選擇在該上下文中執行它的代碼。除非你明確表明它不應該發生。對於所有的意圖和目的,你可以假定這種事情從來沒有發生過(除非你強迫它發生),但在幕後,沒有你需要意識到它,是的,它可能發生。

它是一個,零個還是多個線程?

默認情況下,任務在線程池中執行。線程池將根據其所提供的工作負載而在其包含的線程數量上有所不同。它將從一開始,但如果有足夠需求就會增長,如果需求消失,就會縮小。如果您指定LongRunning選項,則會爲該Task創建一個新線程。如果你指定一個自定義TaskScheduler,你可以讓它做任何你想要的。

它是在同一個核心上執行嗎?

可能但不是確定。

知道,因爲,例如,我可以把睡在主線程的思想,我凍結了後臺工作

把主線程睡眠會防止後臺是非常重要的工作的工作人員。這就是整個創建後臺工作者,這兩項任務不會阻止彼此做工。請注意,如果後臺工作人員嘗試訪問UI以報告進度或顯示結果,並且UI被阻止,那麼他們將等待UI線程在該點處免費。

+1

+1,OP的另一個關於在調試器中查找任務的問題,我將它們指向['Task.Id' /'Task.CurrentId'](http://msdn.microsoft.com/zh-cn/library/ system.threading.tasks.task.id.aspx)(MSDN註釋的是調試器)和[Parallel Tasks窗口](http://msdn.microsoft.com/en-us/library/dd998369.aspx)。 – user7116 2013-03-11 16:25:55

3

您可以使用:

System.Threading.Thread.CurrentThread 

但正如評論中所說,你使用TPL來抽象線程,所以回到這個「低層次」可能是設計不佳的一個指標。

3

Task.Factory.StartNew()將任務排隊以執行(請參閱here)。執行任務以及執行任務的實際線程取決於指定的TaskScheduler(如果沒有指定,則使用當前的TaskScheduler)。

在.Net 4中,默認的TaskScheduler使用ThreadPool執行任務(請參見here),因此如果一個ThreadPool線程排隊該任務,那麼相同的線程稍後可能會執行該任務。

線程數量由ThreadPool決定。

你不應該在乎你的任務在哪個核心上執行。

排隊執行任務將最有可能安排它要在一個線程池線程執行的,所以你不會在意外把主線程設置

+0

如果沒有指定* default *任務調度程序(使用線程池的任務調度程序),則不使用當前任務調度程序。 – Servy 2013-03-11 14:56:11

+1

不符合MSDN文檔。它說調用Factory.StartNew()相當於創建一個Task並調用Task。開始()使用當前。查看我的帖子中的鏈接。 – SpaceghostAli 2013-03-11 15:01:34

相關問題