枚举TaskCreationOption和TaskContinuationOptions
TaskCreationOptions
- None = 0
- PreferFairness = 1
- LongRunning = 2
- AttachedToParent = 4
- DenyChildAttach = 8
- HideScheduler = 16
Task task = new Task(() => { Task task1 = new Task(() => { Thread.Sleep(100); Console.WriteLine("task1"); }, TaskCreationOptions.AttachedToParent); Task task2 = new Task(() => { Thread.Sleep(10); Console.WriteLine("task2"); }, TaskCreationOptions.AttachedToParent); task1.Start(); task2.Start(); }); task.Start(); task.Wait(); //Task.WaitAll(task1,task2); Console.WriteLine("我是主线程!!!!"); Console.Read();
Task task = new Task(() => { Task task1 = new Task(() => { Thread.Sleep(100); Console.WriteLine("task1"); }, TaskCreationOptions.AttachedToParent); Task task2 = new Task(() => { Thread.Sleep(10); Console.WriteLine("task2"); }, TaskCreationOptions.AttachedToParent); task1.Start(); task2.Start(); }, TaskCreationOptions.DenyChildAttach); task.Start(); task.Wait(); //task.WaitAll(task1,task2); Console.WriteLine("我是主线程!!!!"); Console.Read();
HideScheduler:子任务默认不适用父Task的Scheduler,而是使用默认的。(隐藏父Scheduler)
LongRunning:长时间运行的任务建议使用。长时间运行的任务建议new Thread。线程池一些线程被长期占用,新任务到来时,池中线程不够用,会新开线程满足工作需求。而当长时间占用的线程归还线程池时,超出容量的线程需要被释放
PreferFairness:将Task放到线程池全局队列中,让所有Worker 线程争抢(默认会放到线程的本地队列)(本地队列偷队列问题?)
TaskContinuationOptions
- None
- PreferFairness
- LongRunning
- AttachedToParent
- DenyChildAttach
- HideScheduler
- LazyCancellation (解释查看下面Cancellation取消任务一节)
- NotOnRanToCompletion Task1没有正常完成情况下执行ContinueWith
- NotOnFaulted Task1没有出错情况下执行ContinueWith的任务
- OnlyOnCanceled Task1 Canceled才执行ContinueWith的任务
- NotOnCanceled
- OnlyOnFaulted
- OnlyOnRanToCompletion
- ExecuteSynchronously 希望延续的任务使用执行前面任务的线程来执行,Task2使用Task1的线程执行。可以防止线程切换
Cancellation取消任务
Task1.ContinueWith(Task2,CancellationSourceToken)
Task2.ContinueWith(Task3)
如果CancellatioinToken已经取消则T1 -> T2 -> T3 的延续关系在T2处断开,T2取消执行,此时T1和T3没有延续关系,而是并行执行(Task1还没执行就先判断Cancellation,决定是否是取消Task2)
修改代码Task1.ContinueWith(Task2,CancellationSourceToken,LazyCancellation)等待Task1执行完成之后,再判断CancellationSourceToken的状态,保持延续链