创建Task
1.new方式实例化一个Task,需要通过Start方法启动
Task task = new Task(() =>{Thread.Sleep(100);Console.WriteLine($"hello, task1的线程ID为{Thread.CurrentThread.ManagedThreadId}");});task.Start();
2.Task.Factory.StartNew(Action action)创建和启动一个Task
Task task2 = Task.Factory.StartNew(() =>{Thread.Sleep(100);Console.WriteLine($"hello, task2的线程ID为{ Thread.CurrentThread.ManagedThreadId}");});
3.Task.Run(Action action)将任务放在线程池队列,返回并启动一个Task
Task task3 = Task.Run(() =>{Thread.Sleep(100);Console.WriteLine($"hello, task3的线程ID为{ Thread.CurrentThread.ManagedThreadId}");});
task.Status
TaskStatus 枚举
Task对象的状态,可以查看当前task对象是在什么状态
task.Wait()
Task对象的Wait方法会阻塞主线程,不让主线程继续执行,等当前的task对象完成了才继续
Task.WaitAll()
task.Result
Task.Delay()
不要用Thread.Sleep();,这个会阻塞当前线程,有可能是主线程。Task.Delay()创建一个在指定时间后完成的Task。既然是Task,就可以用await等它完成。
用await等它完成,就相当于Thread.Sleep();的效果。但是await不会阻塞当前线程。
在webapi中高并发的场景中,要暂停时间,千万不能用Thread.Sleep();,要用就用await Task.Delay()
Task
如果Task任务有返回值,返回类型就是Task的泛型类型。用Task对象的Result取返回类型的值
Task<string> task1 = new Task<string>(() =>{Thread.Sleep(1000);return "哈哈哈";});task1.Start();Console.WriteLine(task1.Result);
连续任务
如果一个任务的执行依赖于另一个任务,即任务的执行有先后顺序。此时,我们可以使用连续任务。
task.ContinueWith(ReadNews)表示一个任务task结束后,才开始执行另一个任务。
static void Main(string[] args){Task t1 = new Task(() =>{Thread.Sleep(1000);Console.WriteLine("哈哈哈");});Task t2 = t1.ContinueWith(A);Task t3 = t2.ContinueWith(B);t1.Start();Console.ReadKey();}static void A(Task odj){Thread.Sleep(1000);Console.WriteLine("呵呵呵");}static void B(Task odj){Thread.Sleep(1000);Console.WriteLine("嘿嘿嘿");}//打印结果//哈哈哈//呵呵呵//嘿嘿嘿
取消任务CancellationTokenSource
给Task传递一个CancellationToken参数,
static void Main(string[] args) {CancellationTokenSource tokenSource = new CancellationTokenSource();tokenSource.CancelAfter(5000);//5秒钟后请求被取消//还可以手动调用取消,当需要取消Task执行的时候,就手动调用这个//tokenSource.Cancel();Task task = testAsync2(tokenSource.Token);Console.ReadLine();}static Task testAsync2(CancellationToken token) {return Task.Run(() => {int i = 0;while (true) {Console.WriteLine("执行......." + i++);//需要在方法里面判断是不是被取消了,进行取消时的一些操作if (token.IsCancellationRequested) {Console.WriteLine("请求被取消");break;}//如果执行到这一句,请求被取消了,直接抛出异常token.ThrowIfCancellationRequested();}Console.WriteLine("完成");});}
在Async方法中,都可以传递一个
CancellationToken参数进去,设置取消。防止这个异步方法超时什么的。
在WebAPI中,每个Action都可以带一个CancellationToken参数。这参数,请求的时候不用传值。
当http请求被取消的,Action方法也跟着取消。尽量每个方法都传递一个这个值。
[HttpGet("cancel")]public string cancel(CancellationToken toekn) {int i =0;while (true) {Console.WriteLine("执行中...."+i++);if (toekn.IsCancellationRequested) {Console.WriteLine("请求已经取消");toekn.ThrowIfCancellationRequested();}}return "完成";}
