Task Parallel Library01,基本用法
我们知道,每个应用程序就是一个进程,一个进程有多个线程。Task Parallel Library为我们的异步编程、多线程编程提供了强有力的支持,它允许一个主线程运行的同时,另外的一些线程或Task也同时运行。本篇体验基本用法。
基本用法
Taks的构造函数接收的类型是Action,也就是一个委托。
static void Main(string[] args){var t1 = new Task(() =>{Console.WriteLine("任务1开始");Thread.Sleep(1000);Console.WriteLine("任务1结束");});t1.Start();Console.ReadKey();}
如果把方法放到外面。
static void Main(string[] args){var t1 = new Task(() => DoSth(1,2000));t1.Start();Console.ReadKey();}static void DoSth(int id, int sleepTime){Console.WriteLine("任务{0}开始",id);Thread.Sleep(sleepTime);Console.WriteLine("任务{0}结束",id);}
如果有多个Task同时执行。
static void Main(string[] args){var t1 = new Task(() => DoSth(1,2000));t1.Start();var t2 = new Task(() => DoSth(2, 1500));t2.Start();var t3 = new Task(() => DoSth(3, 3000));t3.Start();Console.ReadKey();}
如果有很多Task,每个Task手动启动的话很费事,Task Parallel Library为我们准备了Task工厂。
static void Main(string[] args){var t1 = Task.Factory.StartNew(() => DoSth(1, 2000));var t2 = Task.Factory.StartNew(() => DoSth(2, 1500));var t3 = Task.Factory.StartNew(() => DoSth(3, 3000));Console.ReadKey();}
如果我们想在一个任务结束之后立即执行某个任务,可以使用ContinueWith方法。
static void Main(string[] args){var t1 = Task.Factory.StartNew(() => DoSth(1, 2000)).ContinueWith((pre)=> DoOtherThing(4,2000));var t2 = Task.Factory.StartNew(() => DoSth(2, 1500));var t3 = Task.Factory.StartNew(() => DoSth(3, 3000));Console.ReadKey();}static void DoSth(int id, int sleepTime){Console.WriteLine("任务{0}开始",id);Thread.Sleep(sleepTime);Console.WriteLine("任务{0}结束",id);}static void DoOtherThing(int id, int sleepTime){Console.WriteLine("其他任务{0}开始", id);Thread.Sleep(sleepTime);Console.WriteLine("其他任务{0}结束", id);}
如果希望等待所有的Task执行完毕,使用WaitAll方法。
static void Main(string[] args){var t1 = Task.Factory.StartNew(() => DoSth(1, 2000));var t2 = Task.Factory.StartNew(() => DoSth(2, 1500));var t3 = Task.Factory.StartNew(() => DoSth(3, 3000));var taskList = new List<Task> {t1, t2, t3};Task.WaitAll(taskList.ToArray());Console.WriteLine("我是在所有Task执行完毕后才执行的");Console.ReadKey();}
如果想手动取消结束某个Task,需要为方法带上CancellationToken类型参数。
static void Main(string[] args){var source = new CancellationTokenSource();try{var t1 =Task.Factory.StartNew(() => DoSth(1, 1000, source.Token)).ContinueWith((pre) => DoOtherThing(2, 2000));source.Cancel();}catch (Exception ex){Console.WriteLine(ex.GetType());}Console.WriteLine("haha");Console.ReadKey();}static void DoSth(int id, int sleepTime, CancellationToken token){if (token.IsCancellationRequested){Console.WriteLine("任务被取消");token.ThrowIfCancellationRequested();}Console.WriteLine("任务{0}开始",id);Thread.Sleep(sleepTime);Console.WriteLine("任务{0}结束",id);}static void DoOtherThing(int id, int sleepTime){Console.WriteLine("其他任务{0}开始", id);Thread.Sleep(sleepTime);Console.WriteLine("其他任务{0}结束", id);}
如何从Task从获取方法的返回结果呢?
static void Main(string[] args){Console.WriteLine("开始计算");Task<int> t = Task.Factory.StartNew(() => Sum(1, 2));Console.WriteLine("等待结果");Console.WriteLine(t.Result);Console.ReadKey();}static int Sum(int a, int b){return a + b;}
后面一个Task获取前面一个Task的返回值。
static void Main(string[] args){Task<string> firstTask = Task.Factory.StartNew<string>(() =>{Console.WriteLine("第一个任务开始");return "hi from the one";});Task secondTask = firstTask.ContinueWith((prevoursTask) =>{Console.WriteLine("这里是第二个任务,获取到第一个任务的返回值是{0}",prevoursTask.Result,TaskContinuationOptions.OnlyOnRanToCompletion);});secondTask.Wait();Console.ReadKey();}
等待所有Task完成。
static void Main(string[] args){var t1 = Task.Factory.StartNew(() =>{Console.WriteLine("第一个任务");Thread.Sleep(1000);});var t2 = Task.Factory.StartNew(() =>{Console.WriteLine("第二个任务");Thread.Sleep(1000);});var taskList = new List<Task> {t1, t2};Task.Factory.ContinueWhenAll(taskList.ToArray(), (t) => { Console.WriteLine("所有任务完成我就出来"); });Console.ReadKey();}
如果是嵌套Task。
static void Main(string[] args){Task.Factory.StartNew(() =>{Task child = Task.Factory.StartNew(() =>{Console.WriteLine("我是子任务");}, TaskCreationOptions.AttachedToParent);}).Wait();Console.ReadKey();}
启动Task的几种方式
1、通过Task.Factory.StartNew方法。
static void Main(string[] args){Task.Factory.StartNew(() => SaySth("hello"));Console.ReadKey();}static void SaySth(string msg){Console.WriteLine(msg);}
2、通过Task的Start实例方法
static void Main(string[] args){var t = new Task(() => SaySth("hello"));t.Start();Console.ReadKey();}
或者干脆用委托。
static void Main(string[] args){Task t = new Task(delegate {SaySth("hello");});t.Start();Console.ReadKey();}
3、Task的静态方法Run
static void Main(string[] args){Task t = Task.Run(() => SaySth("hello"));Console.ReadKey();}static void SaySth(string msg){Console.WriteLine(msg);}
一个例子
比如说要下载某个页面,在保持当前UI界面无影响的情况下,使用Task在后台启动任务下载某个页面。
static void Main(string[] args){Console.WriteLine("界面内容");Task<string> r = DownloadAsync("http://www.baidu.com");while (!r.IsCompleted){Console.Write(".");Thread.Sleep(250);}Console.WriteLine(r.Result);Console.ReadKey();}private static string DownloadWebPage(string url){WebRequest request = WebRequest.Create(url);WebResponse response = request.GetResponse();var reader = new StreamReader(response.GetResponseStream());return reader.ReadToEnd();}private static Task<string> DownloadAsync(string url){return Task.Factory.StartNew(() => DownloadWebPage(url));}
Task Parallel Library01,基本用法的更多相关文章
- TPL(Task Parallel Library)多线程、并发功能
The Task Parallel Library (TPL) is a set of public types and APIs in the System.Threading and System ...
- C#5.0之后推荐使用TPL(Task Parallel Libray 任务并行库) 和PLINQ(Parallel LINQ, 并行Linq). 其次是TAP(Task-based Asynchronous Pattern, 基于任务的异步模式)
学习书籍: <C#本质论> 1--C#5.0之后推荐使用TPL(Task Parallel Libray 任务并行库) 和PLINQ(Parallel LINQ, 并行Linq). 其次是 ...
- Using the Task Parallel Library (TPL) for Events
Using the Task Parallel Library (TPL) for Events The parallel tasks library was introduced with the ...
- Winform Global exception and task parallel library exception;
static class Program { /// <summary> /// 应用程序的主入口点. /// </summary> [STAThread] static vo ...
- C#~异步编程再续~大叔所理解的并行编程(Task&Parallel)
返回目录 并行这个概念出自.net4.5,它被封装在System.Threading.Tasks命名空间里,主要提供一些线程,异步的方法,或者说它是对之前Thread进行的二次封装,为的是让开发人员更 ...
- Task Parallel Library02,更进一步
在前一篇中,了解了Task的基本用法 如果一个方法返回Task,Task<T>,如何获取Task的返回值,获取值的过程会阻塞线程吗? static void Main(string[] a ...
- Task/Parallel实现异步多线程
代码: #region Task 异步多线程,Task是基于ThreadPool实现的 { //TestClass testClass = new TestClass(); //Action<o ...
- 异步和多线程,委托异步调用,Thread,ThreadPool,Task,Parallel,CancellationTokenSource
1 进程-线程-多线程,同步和异步2 异步使用和回调3 异步参数4 异步等待5 异步返回值 5 多线程的特点:不卡主线程.速度快.无序性7 thread:线程等待,回调,前台线程/后台线程, 8 th ...
- Task.Factory.StartNew的用法
代码: private void button5_Click(object sender, EventArgs e) { ; Task.Factory.StartNew(() => { Mess ...
随机推荐
- mysql high availability 概述
一.什么是高可用性 1.可用性是指服务不间断运转的时间,通常用百分比来表示,例如 99.999%表示每年最多允许5分钟的宕机时间 2.可用性的效果和开销比例呈线性增长 3.可用性的意义往往也不尽相同, ...
- mysql子查询 exists,not exists,all和any
(1)实现让结果集A - 结果集B:--利用not exists,合并则可用union . exists,not exists:用于判断且获取结果集A是否存在地结果集B中! ==========结果集 ...
- URL传递的参数是UTF-8编码,在打开的页面正常显示(GB2312)的方法
URL传递的参数采用的是UTF-8编码,在打开的子页面中显示乱码, URL传递的地址形如:http://localhost/test.aspx?orgname=%E5%8B%**%**%**%**&a ...
- 绘图: matplotlib核心剖析
参考:http://www.cnblogs.com/vamei/archive/2013/01/30/2879700.html http://blog.csdn.net/ywjun0919/artic ...
- LeetCode(15): 每k个一组翻转链表
hard! 题目描述: 给出一个链表,每 k 个节点为一组进行翻转,并返回翻转后的链表. k 是一个正整数,它的值小于或等于链表的长度.如果节点总数不是 k 的整数倍,那么将最后剩余节点保持原有顺序. ...
- Java编程的逻辑 (72) - 显式条件
本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http: ...
- .NetCore下使用Prometheus实现系统监控和警报 (三)集成Grafana
有了前面InfluxDB的经验,这里就很好处理了,数据类型选择Prometheus选地址等,填好保存 同样通过导入数据处理,我们在https://grafana.com/dashboards上选择Da ...
- 【LOJ】#2511. 「BJOI2018」双人猜数游戏
题解 设\(f[p][a][b]\)表示询问了\(p\)次,答案是\(a,b\)是否会被猜出来 然后判断如果\(p = 1\) 第一个问的\(Alice\),那么\([s,\sqrt{nm}]\)约数 ...
- leetcode 岛屿的个数 python
岛屿的个数 给定一个由 '1'(陆地)和 '0'(水)组成的的二维网格,计算岛屿的数量.一个岛被水包围,并且它是通过水平方向或垂直方向上相邻的陆地连接而成的.你可以假设网格的四个边均被水包 ...
- AFO 我的oi生涯 大结局
今儿个哥几个一屋子退役了,这两天也许会写一个生涯大结局留作纪念吧. 今天就写了吧. 由于在机房的原因比一般同学获得的知识更多一些.进来总是看新闻,感慨颇多.自从两会开的第一天起,我就对我们政府采取的一 ...