从这篇文章开始,我想直接进入关于Task的一些内容,有时间再回顾Threadpool的相关内容。
我一开始接触Task就觉得他和Thread很像,都是开新的线程。但是两者有很多区别,其中比较明显的是:Task创建的是线程池任务,而Thread默认创建的是前台任务。
同Thread一样,Task可以使用lambda表达式来构造action,作为Task的构造函数参数。如下:
1、先定义一个函数TaskMethod,他接受name作为字符串参数。
static void TaskMethod(string name) { Console.WriteLine("Task {0} 运行在线程id为{1}的线程上. 是否是线程池中线程?:{2}", name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread); }
2、新建Task实例,并且 Start():
var t1 = new Task(() => TaskMethod("Task 1")); t1.Start();
因为Task接受无参数和返回值的Action作为构造器参数,因此此处可以使用如上的lambda表达式,在表达式中传参"Task 1"。
运行结果如下:
可以很明显的看出,该Task(t1)运行在线程池中。
必须要指出的是,线程池一般只运行执行时间较短的异步操作,需要长时间执行的操作尽量不要使用线程池。
除了上面这种开Task的方法,还有两种常见的用法,分别是 Task.Run() 和 Task.Factory.StartNew()。两者的区别在于后者能传入一些额外参数,以丰富Task的运行选项。例如:
Task.Run(() => TaskMethod("Task 3")); Task.Factory.StartNew(() => TaskMethod("Task 4")); Task.Factory.StartNew(() => TaskMethod("Task 5"), TaskCreationOptions.LongRunning);
第二句则使用了Task.Factory.StartNew()默认方法,最后一句加入了选项“LongRunning”,意味着该任务将长时间运行,因此他不是在线程池中执行。
结果如下:
注意:Task的运行有一定的随机性,开始次序会有变化!