C# Task
一、主线程阻塞
1、阻塞等待所有线程执行结束,再执行下面的操作
语法:Task.WaitAll(task数组);
2、阻塞等待任一线程执行结束,再执行下面的操作
语法:Task.WaitAny(task数组);
3、案例
private void btnTask_Click(object sender, EventArgs e) { Console.WriteLine("开始执行"); List<Task> tasks = new List<Task>(); tasks.Add(Task.Run(() => { this.Print("小新", "1"); })); tasks.Add(Task.Run(() => { this.Print("小白", "2"); })); tasks.Add(Task.Run(() => { this.Print("小葵", "3"); })); tasks.Add(Task.Run(() => { this.Print("阿呆", "4"); })); // 阻塞,直到任一线程执行完毕 Task.WaitAny(tasks.ToArray()); Console.WriteLine("有一位小朋友到了,准备游戏"); // 集合转化成数组,阻塞直到线程执行完毕 Task.WaitAll(tasks.ToArray()); Console.WriteLine("所有小朋友到了,开始玩扮家家酒"); Console.WriteLine("结束执行"); } private void Print(string name, object project) { Console.WriteLine($"开启线程-线程名字:{Thread.CurrentThread.ManagedThreadId.ToString("00")}-用户名:{name}-项目名:{project}"); Thread.Sleep(1000*2); Console.WriteLine($"结束线程-线程名字:{Thread.CurrentThread.ManagedThreadId.ToString("00")}-用户名:{name}-项目名:{project}"); }
缺点:阻塞主线程,窗口没法移动
二、TaskFactory
1、创建一个延续任务,当所有线程(数组)执行完毕后执行延续任务
语法:
TaskFactory taskFactory = new TaskFactory()
taskFactory.ContinueWhenAll(线程数组,延续任务)
2、创建一个延续任务,当任一线程(数组)执行完毕后执行延续任务
语法:
TaskFactory taskFactory = new TaskFactory();
taskFactory.ContinueWhenAny(task数组, 后续任务);
优点:线程列表的后续任务受控,与主线程异步不影响窗口
缺点:无法在主线程中执行,所有线程执行完后,再执行的任务,需要和WaitAll()一起使用,taskFactoy也是一个task
3、案例
private void btnTask_Click(object sender, EventArgs e) { Console.WriteLine("开始执行"); List<Task> tasks = new List<Task>(); tasks.Add(Task.Run(() => { this.Print("小新", "1"); })); tasks.Add(Task.Run(() => { this.Print("小白", "2"); })); tasks.Add(Task.Run(() => { this.Print("小葵", "3"); })); tasks.Add(Task.Run(() => { this.Print("阿呆", "4"); })); TaskFactory taskFactory = new TaskFactory(); // 创建一个延续任务,当线程数组任一线程执行完毕后,执行这个延续任务 taskFactory.ContinueWhenAny(tasks.ToArray(), (_) => { Console.WriteLine($"有一个小朋友到了,开始选择游戏,线程-{Thread.CurrentThread.ManagedThreadId}"); }); // 创建一个延续任务,等待所有线程结束后执行 taskFactory.ContinueWhenAll(tasks.ToArray(), (_) => { Console.WriteLine($"所有小朋友都到了,开始进行游戏。线程-{Thread.CurrentThread.ManagedThreadId}"); }); // 与子线程异步 Console.WriteLine("执行结束"); } private void Print(string name, object project) { Console.WriteLine($"开启线程-线程名字:{Thread.CurrentThread.ManagedThreadId.ToString("00")}-用户名:{name}-项目名:{project}"); Thread.Sleep(1000*2); Console.WriteLine($"结束线程-线程名字:{Thread.CurrentThread.ManagedThreadId.ToString("00")}-用户名:{name}-项目名:{project}"); }
4、与WaitAll()一起使用
private void btnTask_Click(object sender, EventArgs e) { Console.WriteLine("开始执行"); List<Task> tasks = new List<Task>(); tasks.Add(Task.Run(() => { this.Print("小新", "1"); })); tasks.Add(Task.Run(() => { this.Print("小白", "2"); })); tasks.Add(Task.Run(() => { this.Print("小葵", "3"); })); tasks.Add(Task.Run(() => { this.Print("阿呆", "4"); })); TaskFactory taskFactory = new TaskFactory(); // 创建一个延续任务,当线程数组任一线程执行完毕后,执行这个延续任务 taskFactory.ContinueWhenAny(tasks.ToArray(), (_) => { Console.WriteLine($"有一个小朋友到了,开始选择游戏,线程-{Thread.CurrentThread.ManagedThreadId}"); }); // 创建一个延续任务,等待所有线程结束后执行 tasks.Add(taskFactory.ContinueWhenAll(tasks.ToArray(), (_) => { Console.WriteLine($"所有小朋友都到了,开始进行游戏。线程-{Thread.CurrentThread.ManagedThreadId}"); })); // taskFactory也是一个task Task.WaitAll(tasks.ToArray()); // 与子线程异步 Console.WriteLine("执行结束"); } private void Print(string name, object project) { Console.WriteLine($"开启线程-线程名字:{Thread.CurrentThread.ManagedThreadId.ToString("00")}-用户名:{name}-项目名:{project}"); Thread.Sleep(1000*2); Console.WriteLine($"结束线程-线程名字:{Thread.CurrentThread.ManagedThreadId.ToString("00")}-用户名:{name}-项目名:{project}"); }

浙公网安备 33010602011771号