文章目录
一、前言
在.NET平台使用C#进行编程时,遇到了并行操作的需求,于是上网一搜多线程,一个非常简单语句出现了:
Task.Factory.StartNew(() =>
{
});
还有,
Task.Run(() =>
{
});
于是,拿来一用,往花括号中填入一些业务代码。
“嗯,确实是多线程。”
我在其他平台使用多线程的印象当中,使用多线程都是先建一个线程对象,然后往里面填许多参数,然后还要手动启停。
Thread thread = new Thread(p1, p2, func, 一堆看不懂的参数);
thread.Start();
...中间省略一万步
thread.Abort();
相比之下,.net平台这种极简的多线程操作方法对新手真是友好。(毕竟是微软的嘛,非常善于对底层复杂应用抽象,到应用层程序员这一侧,只管用就行了)。
随着项目的进行,并行操作越来越复杂,我也愈来愈觉得不能就这么简单一用就完事了,得稍微了解下它的特性以及使用时的注意项。
二、认识
于是上网搜了下C# Task使用,大部分都是翻译了一下微软官方文档里的东西(而且是自带的机翻)。那既然如此,我也试着结合官方文档来理解一下。
下文出现的Task、task和任务基本上就是指一个东西,结合语境体会,不过一般首字母大写根据微软的习惯应该是表示类。
2.1. 基于任务的多线程编程
Task并行库(就是你用Task这个东西的相关库,全名Task Parallel Library,简称TPL)是基于Task这个概念的,它代表了一个并行操作。也确实,如果你对一个不玩编程的人说某个线程xxx,人家可能听不懂,线程明显是个专业术语嘛;如果说任务,是不是感觉更贴近现实了呢。
某种程度上来说,一个task类似于thread(线程)或者ThreadPool工作项(线程池的一项嘛,还是线程),但是它处在一个更高的抽象层面上(毕竟本质上还是线程嘛?大概吧)。
接着,文档还亲民地解释了一下,“并行任务”这个术语指的是一个或者多个独立的任务同时进行。
Task提供了两点基本的好处:
- 更效率且更灵活的使用系统资源。
在背后呢(通常说在底层实现上),任务是排在线程池当中的,并且它用了一些算法(决策、调整线程数量和提供了负载均衡以加大吞吐量)进行增强。这使得任务相对轻量级,你可以创建许多任务使得并行操作更精细化。 - 相比使用线程或者线程池,有更多的程序模块可以使用。
任务和平台框架(指.NET这个平台吧)提供了丰富的API支持waiting, cancellation, continuations, robust exception handling, detailed status, custom scheduling等功能。
因此,对于在.NET上使用多线程、异步操作和并行代码的你来说,TPL是更好的API(也就是说,在.NET下,微软非常建议你使用Task)。
看完这一段,很明显感觉到微软在说它好用,但是底层实现上是一笔带过的,就讲了它底层是用了线程池那一套的,并且有所优化(我开始有点理解,为什么大家都说,微软的东西好入