Task的任务延续

一:ContinueWith

1.Task=>Task.CreationOptions 第一task

2.Task=>TaskContinuationOptions 第二个task

第二个task需要判断第一个task在什么情况下,我该执行或者不该执行。。

二:LazyCancellation

1.Cancellation判断任务的取消。。。相当于Thread about

1
2
3
4
5
6
7
8
9
10
11
12
13
14
CancellationTokenSource source = new CancellationTokenSource();//判断任务延续
source.Cancel();
Task task1 = new Task(() => {
//Thread.Sleep(1000);
Console.WriteLine("task1, tid={0},dt={1}", Thread.CurrentThread.ManagedThreadId, DateTime.Now.ToString("HH:mm:ss"));
});
var task2 = task1.ContinueWith(t => {
Console.WriteLine("task2,tid={0},dt={1}", Thread.CurrentThread.ManagedThreadId, DateTime.Now.ToString("HH:mm:ss"));
}, source.Token);
var task3 = task2.ContinueWith(t => {

Console.WriteLine("task3,tid={0},dt={1},task2={2}", Thread.CurrentThread.ManagedThreadId, DateTime.Now.ToString("HH:mm:ss"), task2.Status);
});
task1.Start();

1572882705464

正常执行顺序:task1->ContinueWith task2->ContinueWith task3

结果执行顺序: task3->task1

解释:ContinueWith的时候,预先判断了source.Token的值,结果发现任务已经取消,这个时候,task2和task1没有延续的关系,所以task3和task1可以并行,看似ContinueWith的关系得不到延续【并行】

1572882940405

使用TaskContinuationOptions.LazyCancellation

1
2
3
4
5
6
7
8
9
10
11
12
13
14
CancellationTokenSource source = new CancellationTokenSource();//判断任务延续
source.Cancel();
Task task1 = new Task(() => {
//Thread.Sleep(1000);
Console.WriteLine("task1, tid={0},dt={1}", Thread.CurrentThread.ManagedThreadId, DateTime.Now.ToString("HH:mm:ss"));
});
var task2 = task1.ContinueWith(t => {
Console.WriteLine("task2,tid={0},dt={1}", Thread.CurrentThread.ManagedThreadId, DateTime.Now.ToString("HH:mm:ss"));
}, source.Token,TaskContinuationOptions.LazyCancellation, TaskScheduler.Current);
var task3 = task2.ContinueWith(t => {
Console.WriteLine("task3,tid={0},dt={1},task2={2}", Thread.CurrentThread.ManagedThreadId, DateTime.Now.ToString("HH:mm:ss"), task2.Status);
});
task1.Start();
Console.Read();

1572883135949

TaskContinuationOptions.LazyCancellation当task2被取消了,还是先执行等待线程执行完成,在执行后面的线程

三:ExecuteSynchronously

同步执行任务,2个线程用同一个线程执行,可以减少时间片切换

1
2
3
4
5
6
7
8
9
10
11
12
Task task1 = new Task(() => {
Thread.Sleep(1000);
Console.WriteLine("task1, tid={0},dt={1}", Thread.CurrentThread.ManagedThreadId, DateTime.Now.ToString("HH:mm:ss"));
});
var task2 = task1.ContinueWith(t => {
Console.WriteLine("task2,tid={0},dt={1}", Thread.CurrentThread.ManagedThreadId, DateTime.Now.ToString("HH:mm:ss"));
},TaskContinuationOptions.ExecuteSynchronously);
var task3 = task2.ContinueWith(t => {
Console.WriteLine("task3,tid={0},dt={1},task2={2}", Thread.CurrentThread.ManagedThreadId, DateTime.Now.ToString("HH:mm:ss"), task2.Status);
});
task1.Start();
Console.Read();

1572883421282

上图使用TaskContinuationOptions.ExecuteSynchronously,task1和task2使用同一个线程执行任务。

不使用TaskContinuationOptions.ExecuteSynchronously的结果:

1572883467747

四:NotOnRanToCompletion和OnlyOnRanToCompletion

前者表示延续任务必须在非完成状态才能执行

后者表示延续任务必须在完成状态才能执行

五:NotOnFaulted和OnlyOnFaulted

前者表示延续任务必须在非失败状态才能执行

后者表示延续任务必须在失败状态才能执行

六:NotOnCanceled和OnlyOnCanceled

前者表示延续任务必须在非取消状态才能执行

后者表示延续任务必须在取消状态才能执行