C# 并行编程 Task
1. 创建Task
创建Task的方法有两种,一种是直接创建——new一个出来,一种是通过工厂创建。
//第一种创建方式,直接实例化 var task1 = new Task(() => { //TODO you code });
task1.Start();
这是最简单的创建方法,可以看到其构造函数是一个Action。
//第二种创建方式,工厂创建 var task2 = Task.Factory.StartNew(() => { //TODO you code });
这种方式通过静态工厂,创建以个Task并运行。
通过构造函数创建的task,必须手动Start,而通过工厂创建的Task直接就启动了。
2. Task的简略生命周期(状态):
Created:表示默认初始化任务,但是“工厂创建的”实例直接跳过。
WaitingToRun: 这种状态表示等待任务调度器分配线程给任务执行。
RanToCompletion:任务执行完毕。
3. Task的任务控制
Task最吸引人的地方就是他的任务控制了,你可以很好的控制task的执行顺序,让多个task有序的工作。
Task.Wait 就是等待任务执行完成
Task.WaitAll 就是等待所有的任务都执行完成
Task.WaitAny 就是等待任何一个任务完成就继续向下执行
Task.ContinueWith 就是在第一个Task完成后自动启动下一个Task,实现Task的延续
Task的取消 比如我们启动了一个task,出现异常或者用户点击取消等等,我们要取消这个任务,这时我们通过cancellation的tokens来取消一个Task。在很多Task的Body里面包含循环,我们可以在轮询的时候判断IsCancellationRequested属性是否为True,如果是True的话就return.
var tokenSource = new CancellationTokenSource(); var token = tokenSource.Token; var task = Task.Factory.StartNew(() => { for (var i = 0; i < 1000; i++) { System.Threading.Thread.Sleep(1000); if (token.IsCancellationRequested) { Console.WriteLine("Abort mission success!"); return; } } }, token); token.Register(() => { Console.WriteLine("Canceled"); }); Console.WriteLine("Press enter to cancel task..."); Console.ReadKey(); tokenSource.Cancel();
Console.ReadKey();
这里开启了一个Task,并给token注册了一个方法,输出一条信息,然后执行ReadKey开始等待用户输入,用户点击回车后,执行tokenSource.Cancel方法,取消任务。
4. Task的异常处理
static void Main(string[] args)
{
try
{
var pTask = Task.Factory.StartNew(() =>
{
var cTask = Task.Factory.StartNew(() =>
{
System.Threading.Thread.Sleep(2000);
throw new Exception("cTask Error!");
Console.WriteLine("Childen task finished!");
});
throw new Exception("pTask Error!");
Console.WriteLine("Parent task finished!");
});
pTask.Wait();
}
catch (AggregateException ex)
{
foreach (Exception inner in ex.InnerExceptions)
{
Console.WriteLine(inner.Message);
}
}
Console.WriteLine("Flag");
Console.Read();
}
这里用了AggregateException,就是异常集合,才能捕获到真正的异常信息。