一.介绍
Task类通常以异步方式执行,Task对象是基于任务的异步模式引入到.NET Framework 4中。
二.任务实例化
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace MyTask { class Program { static void Main(string[] args) { Action<object> action = (object obj) => { Thread.Sleep(1000); Console.WriteLine("obj:{0}", obj); }; Task t1 = new Task(action, "带参数的任务"); t1.Start(); Console.ReadKey(); } } }
上述实例中任务t1通过调用任务类构造函数实例化,并通过调用Start()方法执行任务;它执行Action<object>名为action的委托,这样它就可以接受object类型的变量。
三.创建和执行任务
Task可能在不同的方式中创建实例,我们最常用的方法就是调用静态Run方法,Run方法提供了简单的方法来启动任务。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace MyTask { class Program { static void Main(string[] args) { Task.Run(() => { Thread.Sleep(1000); Console.WriteLine("任务执行中。。。"); }); Console.WriteLine("主线程执行中。。。"); Console.ReadKey(); } } }
它可以使用静态方法TaskFactory.StartNew方法来替换;而Task.Factory属性返回TaskFactory对象,重载的TaskFactory.StartNew方法启动任务。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace MyTask { class Program { static void Main(string[] args) { TaskFactory factory = new TaskFactory(); Task task1 = factory.StartNew(() => { Console.WriteLine("任务1执行中。。。"); }); Task task2 = Task.Factory.StartNew(() => { Console.WriteLine("任务2执行中。。。"); }); Console.WriteLine("主线程执行中。。。"); Console.ReadKey(); } } }
四.等待一个或多个任务完成
任务通常是以异步方式运行在线程上,创建并启动任务的线程将继续执行,在某些情况下,应用程序需要调用线程继续执行下去,而此时一个或多个任务并没有执行完毕,如果你想要等待这些任务执行完成后,应用程序才能继续执行下去,那么可以通过调用Wait方法来等待一个或多个任务完成。Task.Wait()方法是无条件等待,就是说只要任务不完成,它就会一直阻塞等待。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace MyTask { class Program { static void Main(string[] args) { Console.WriteLine("主程序开始执行。。。"); TaskFactory factory = new TaskFactory(); Task task = factory.StartNew(() => { Thread.Sleep(1000); Console.WriteLine("任务执行完成。。。"); }); task.Wait(); Console.WriteLine("主线程执行完成。。。"); Console.ReadKey(); } } }
五.WaitAny和WaitAll的使用
在某些情况下,我们只需要等待多个任务中的其中一个,而等待哪个任务并不需要明确指明,那么此时WaitAny就派上用场了;
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace MyTask { class Program { static void Main(string[] args) { MyWaitAny(); Console.ReadKey(); } private static void MyWaitAny() { var tasks = new Task[3]; var rnd = new Random(); for (int i = 0; i <= 2; i++) { tasks[i] = Task.Run(() => Thread.Sleep(rnd.Next(500, 3000))); } try { //返回值:已完成的任务在 tasks 数组参数中的索引。 int index = Task.WaitAny(tasks); Console.WriteLine("Task {0} completed first", tasks[index].Id); Console.WriteLine("Status of all tasks:"); foreach (var t in tasks) { Console.WriteLine("Task {0}:{1}", t.Id, t.Status); } } catch (Exception e) { Console.WriteLine(e.ToString()); } } } }
如果需要等待所有任务完成后,程序才可以继续执行下去,那么WaitAll()无疑是一个比较好的方法。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace MyTask { class Program { static void Main(string[] args) { MyWaitAll(); Console.ReadKey(); } private static void MyWaitAll() { Task[] tasks = new Task[10]; for(int i = 0; i < 10; i++) { tasks[i] = Task.Run(() => Thread.Sleep(2000)); } try { Task.WaitAll(tasks); } catch(Exception e) { Console.WriteLine(e.ToString()); } Console.WriteLine("Status of Completed tasks:"); foreach(var t in tasks) { Console.WriteLine("Task {0}:{1}", t.Id, t.Status); } } } }
想要了解更多关于Task类的相关信息,请访问微软官方文档:https://docs.microsoft.com/zh-cn/dotnet/api/system.threading.tasks.task?view=netframework-4.5