直接上代码;说明直接代码里面
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace ConsoleApp1.TaskTest { public class TaskUse { /* *Task是微软在.Net 4.0时代推出来的,也是微软极力推荐的一种多线程的处理方式,Task看起来像一个Thread,实际上,它是在ThreadPool * 的基础上进行的封装,Task的控制和扩展性很强,在线程的延续、阻塞、取消、超时等方面远胜于Thread和ThreadPool。 * */ /// <summary> /// 第一种:单独启动线程 /// </summary> public void Task1() { var task = new Task(()=> { Console.WriteLine("启动线程"); }); task.Start(); } /// <summary> /// 第二种:静态方法调用,第一种的简写方式 /// </summary> public void Task2() { Task.Run(()=>{ Console.WriteLine("启动线程"); }); } /// <summary> /// 第三种:线程池的启动方式,执行时间短,不需要开启线程开销 /// </summary> public void Task3() { Task.Factory.StartNew(()=> { Console.WriteLine("启动线程"); }); } /// <summary> /// 第四种:同步启动,会卡住主线程 /// </summary> public void Task4() { var task = new Task(()=> { Console.WriteLine("启动线程"); }); task.RunSynchronously(); } /* * Task下的线程等待和延续主要以下几类: ①. Wait:针对单个Task的实例,可以task1.wait进行线程等待. <Task的实例方法> ②. WaitAny:执行的线程等待其中任何一个线程执行完毕即可执行(如果主线程执行,则卡主线程) <Task的静态方法> ③. WaitAll:执行的线程等待其中所有线程执行完毕方可执行(如果主线程执行,则卡主线程) <Task的静态方法> ④. WhenAny:与下面ContinueWith配合执行,当传入的线程中任何一个线程执行完毕,继续执行ContinueWith中的任务(属于开启新线程,不卡主线程) <Task的静态方法> ⑤. WhenAll:与下面ContinueWith配合执行,当传入的线程中所有线程执行完毕,继续执行ContinueWith中的任务(属于开启新线程,不卡主线程) <Task的静态方法> ⑥. ContinueWith:和上面WhenAny和WhenAll配合使用 <Task的实例方法> */ /// <summary> /// async、await写法 /// </summary> /// <param name="i"></param> /// <returns></returns> public async Task<int> Task22(int i) { return await Task.Run(() => { Thread.Sleep(i * 1000); Console.WriteLine($"当前执行线程为:{Thread.CurrentThread.ManagedThreadId},时间{DateTime.Now.ToString("hh:mm:ss fff")}"); return Thread.CurrentThread.ManagedThreadId; }); } public Task Task221(int i) { return Task.Run(() => { Thread.Sleep(i * 1000); Console.WriteLine($"当前执行线程为:{Thread.CurrentThread.ManagedThreadId},时间{DateTime.Now.ToString("hh:mm:ss fff")}"); }); } /// <summary> /// 测试WaitAny /// </summary> public void TaskWait1() { Task[] tasks =new Task[5]; for (int i = 0; i < 5; i++) { tasks[i] = Task221(i); } int result = Task.WaitAny(tasks); Console.WriteLine($"执行完毕线程为:{result},时间{DateTime.Now.ToString("hh:mm:ss fff")}"); } /*执行结果: * 当前执行线程为:7,时间10:37:18 056 * 执行完毕线程为:0,时间10:37:18 060 当前执行线程为:4,时间10:37:19 056 当前执行线程为:3,时间10:37:20 057 当前执行线程为:6,时间10:37:21 057 当前执行线程为:5,时间10:37:22 057 */ public void TaskWait2() { Task[] tasks = new Task[5]; for (int i = 0; i < 5; i++) { tasks[i] = Task221(i); } Task.WaitAll(tasks); Console.WriteLine($"执行完毕线程为:{Thread.CurrentThread.ManagedThreadId},时间{DateTime.Now.ToString("hh:mm:ss fff")}"); } /*执行结果: * 当前执行线程为:4,时间10:35:51 055 当前执行线程为:3,时间10:35:52 057 当前执行线程为:7,时间10:35:53 057 当前执行线程为:8,时间10:35:54 060 当前执行线程为:6,时间10:35:55 084 执行完毕线程为:1,时间10:35:55 084 */ public void TaskWait3() { Task[] tasks = new Task[5]; for (int i = 0; i < 5; i++) { tasks[i] = Task221(i); } //任何线程执行完毕开启新进程继续执行 Task.WhenAny(tasks).ContinueWith((m)=> { Console.WriteLine($"执行完毕线程为:{Thread.CurrentThread.ManagedThreadId},参数{m.Id},时间{DateTime.Now.ToString("hh:mm:ss fff")}"); }); } /*执行结果: 当前执行线程为:3,时间10:42:31 127 执行完毕线程为:5,参数6,时间10:42:31 155 当前执行线程为:4,时间10:42:32 129 当前执行线程为:6,时间10:42:33 129 当前执行线程为:7,时间10:42:34 128 当前执行线程为:8,时间10:42:35 133 */ public void TaskWait4() { Task[] tasks = new Task[5]; for (int i = 0; i < 5; i++) { tasks[i] = Task221(i); } //所有线程执行完毕开启新进程继续执行 Task.WhenAll(tasks).ContinueWith((m) => { Console.WriteLine($"执行完毕线程为:{Thread.CurrentThread.ManagedThreadId},参数{m.Id},时间{DateTime.Now.ToString("hh:mm:ss fff")}"); }); } /*执行结果: 当前执行线程为:3,时间10:44:37 197 当前执行线程为:6,时间10:44:38 198 当前执行线程为:5,时间10:44:39 198 当前执行线程为:8,时间10:44:40 199 当前执行线程为:3,时间10:44:41 202 执行完毕线程为:4,参数6,时间10:44:41 202 */ } }