2013-06-27 90 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

哦。好。第二个编辑更清晰。 –