Task Parallel Library01,基本用法
2024-10-11 03:15:46
我们知道,每个应用程序就是一个进程,一个进程有多个线程。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));}
最新文章
- 【极品代码】一般人我不告诉他,手机端h5播放时不自动全屏代码
- 第八十八天请假 PHP smarty模板 变量调节器,方法和块函数基本书写格式
- HDU 4788 Hard Disk Drive (2013成都H,水题) 进位换算
- poj2251 三维简单BFS
- Netty IO线程模型学习总结
- 一个基于DpperHelper的t4模板
- 手动清除memcached缓存方法
- layui模板引擎
- Chapter 4 Invitations——20
- 长短时记忆网络LSTM和条件随机场crf
- 【树形dp入门】没有上司的舞会 @洛谷P1352
- elasticsearch使用bulk实现批量操作
- [HNOI2010] 城市建设_动态最小生成树(Dynamic_MST)
- 学习笔记27—python中numpy.ravel() 和 flatten()函数
- 初级字典树查找在 Emoji、关键字检索上的运用 Part-2
- OI回忆录第一章 逐梦之始
- Cocos2d-x之Schedule
- [转]MySQL主从复制(Master-Slave)与读写分离(MySQL-Proxy)实践
- 三、oracle 用户管理一
- MySQL 快速入门
热门文章
- git使用常用命令
- mysql Keepalived 实践
- Python常用time处理
- K-means聚类算法的三种改进(K-means++,ISODATA,Kernel K-means)介绍与对比
- js ES6 Set和Map数据结构详解
- VirtualBox 安装 Gentoo 小记
- 如何区分prometheus中Histogram和Summary类型的metrics?
- Codeforces Round #533 (Div. 2) E - Helping Hiasat 最大团
- ES6+Webpack 下使用 Web Worker
- java集合类TreeMap和TreeSet