2013-06-27 127 views
1

爲什麼一個線程(其中我設置IsBackgroundthreadTrue沒有與線程池線程一起運行?新的線程()和線程池?

/*1*/ volatile bool r = false; 
/*2*/ var g= new Thread(() => r=Thread.CurrentThread.IsThreadPoolThread); 
/*3*/ g.IsBackground = true; 
/*4*/ g.Start(); 
/*5*/ g.Join(); 
/*6*/ Console.WriteLine(r); //false 

儘管此代碼(顯然)確實在線程池線程上運行?

Task.Factory.StartNew(()=>Console.Write(Thread.CurrentThread.IsThreadPoolThread)); //true 
Console.ReadLine(); 

p.s. (我知道任務是(默認情況下)在後臺線程運行,並且它們在線程池中運行,但我的問題與我設置線程在後臺運行的類似情況有關。)

+0

「我知道任務總是後臺線程」並不總是,如果你設置了一個TaskScheduler,那麼Task任何地方都可以運行。 – svick

+0

@svick確實。 (我的意思是默認)生病的改變。 –

回答

4

IsBackground屬性不會執行您認爲它的操作。它僅僅是一個標誌,告訴CLR在非後臺線程完成時放棄線程是否可行,包括程序的主線程。如果是false,則默認值,那麼CLR不會干擾該線程,從而允許它完成。將其設置爲true將調用Thread.Abort()的等價值,減去線程對它做任何事情或被通知它的能力。粗魯的中止。

由Thread類創建的線程永遠不會合並,除非使用某種自定義CLR主機,這非常少見。創建線程池線程的常用方法是ThreadPool.QueueUserWorkItem,()BackgroundWorker,委託的BeginInvoke()方法和Task類。

+1

後臺線程在所有forground線程結束時結束,而不是在主線程結束時結束。新產生的forground線程將保持後臺線程活着。 – Servy

6

ThreadPool是由運行時管理的專用線程池。

用戶創建的後臺線程不是線程池的一部分。

換句話說,所有線程池線程都是後臺線程,但並非所有的後臺線程都是線程池線程。

+0

爲什麼?任務與我的Backgroundthread有什麼區別? (除了連續性等...) –

+1

哦。好。第二個編輯更清晰。 –