创建时常用的枚举:
None、PreferFairness、LongRunning、AttacthedToParent、DenyChildAttach、HideScheduler
AttacthedToParent:
背景代码如下
using System; using System.Threading; using System.Threading.Tasks; namespace 多线程_List { class Program { static void Main(string[] args) { //创建了一个线程1 Task t = Task.Factory.StartNew(() => { Console.WriteLine("thread 1"); Task t1 = new Task(() =>{ Thread.Sleep(100); Console.WriteLine( "task 11"); }); Task t2 = new Task(() => { Console.WriteLine("task 12"); }); t1.Start(); t2.Start(); //下面continue中的新的线程 肯定是在 线程1之后 //但是在线程1里面又另外启用了2 个线程 continue中的线程就未必在这两个线程执行完之后执行 }).ContinueWith(_t=> { Console.WriteLine("thread 2"); }); Console.ReadKey(); } } }
thread 1
thread 2
task 12
task 11
这时 如果要continue中启用的线程在task t内部所有线程执行完毕之后再执行可以使用 AttacthedToParent枚举
using System; using System.Threading; using System.Threading.Tasks; namespace 多线程_List { class Program { static void Main(string[] args) { //创建了一个线程1 Task t = Task.Factory.StartNew(() => { Console.WriteLine("thread 1"); Task t1 = new Task(() => { Thread.Sleep(100); Console.WriteLine("task 11"); }, TaskCreationOptions.AttachedToParent); Task t2 = new Task(() => { Console.WriteLine("task 12"); }, TaskCreationOptions.AttachedToParent); t1.Start(); t2.Start(); //下面continue中的新的线程 肯定是在 线程1之后 //但是在线程1里面又另外启用了2 个线程 continue中的线程就未必在这两个线程执行完之后执行 }).ContinueWith(_t => { Console.WriteLine("thread 2"); }); //如果不允许t1 和 t2附加到t上面 //}, TaskCreationOptions.DenyChildAttach).ContinueWith(_t => //{ // Console.WriteLine("thread 2"); //}); Console.ReadKey(); } } }
执行结果:
thread 1
task 12
task 11
thread 2
AttacthedToParent的效果相当于t.WaitAll(t1,t2)
LongRunning :长时间运行的任务 ,如果你明知道是长时间执行的,建议你使用此枚举。因为这个枚举创建的线程是一个新建的Thread 而不是线程池的线程。为什么要这么搞呢,因为如果你不这么搞,使用的是线程池的线程,线程池的线程长期少一个的话,线程池会再创建一个线程,当你这个线程执行完毕还给线程池的时候,线程池的线程就比原来的线程池多一个,导致线程池线程过多,导致cpu切换时间变长等问题。
PreferFairness 让各个线程看起来公平点,会将task扔到ThreadPool的全局队列中,让workthread进行争抢,不这样搞默认会放进thread的一个本地队列中。