C#多线程开发-任务并行库04
你好,我是阿辉。
之前学习了线程池,知道了它有很多好处。
使用线程池可以使我们在减少并行度花销时节省操作系统资源。可认为线程池是一个抽象层,其向程序员隐藏了使用线程的细节,使我们可以专心处理程序逻辑,而不是各种线程问题。
但也不是说我们所有的项目中都上线程池,其实它也有很多弊端,比如我们需要自定义使用异步委托的方式才可以将线程中的消息或异常传递出来。这些如果在一个大的软件系统中,会导致软件结构过于混乱,各个线程之间消息传递来传递去的,如果发生没有处理掉的异常,很容易导致软件出现致命错误。
为了解决这个问题,在.Net Framework 4.0中引入了一个新的异步操作的API,它叫任务并行库(TPL)。
那么接下来,让我们一起来认识一下这个TPL,看看它到底有什么魔力可以把线程池中的棘手问题解决掉。
任务并行库
TPL又被认为是线程池的有一个抽象,其对程序员隐藏了线程池交互的底层代码,并只提供了更方便的细粒度的API。
TPL的核心是任务。一个任务代表一个异步操作,该操作可以通过多种方式运行,可以使用或不使用独立线程运行。
TPL有一个关键优势,就是一个任务可以通过多种方式和其它任务组合起来。
比如可以同时开启多个任务,等待所有任务完成,然后运行一个任务对之前所有任务的结果进行一些计算。
可以使用AggregateException来捕获底层任务内部所有异常,并允许单独处理这些异常。在C#5.0中已经内置了对TPL的支持,允许我们使用心得await和async关键字以平滑的、舒服的方式操作任务。
一、创建任务
可以通过下面三种方式来创建任务。
var a1 = new Task(()=>TastMethod("线程01"));
a1.Start();
Task.Run(()=>TastMethod("线程001")); //已弃用
Task.Factory.StartNew(()=>TastMethod("线程02"));
Task.Factory.StartNew(() => TastMethod("线程03"),TaskCreationOptions.LongRunning);
Console.ReadKey();
在最新的.NET 5.0中已经将任务快速启动方式Run,丢弃掉了。只能使用其余的两种。实例化的Tast属性,必须进行启动,任务才可以执行。其余的.NET已经做了内置,只需要使用就默认自动开启。
在线程3开启过程中,增加了TaskCreationOptions.LongRuning参数,它表示标记该任务为长时间运行,结果该任务将不会使用线程池,而在单独的线程中运行。然而根据运行该任务的当前任务调度程序,运行方式可能不同。
二、使用任务执行基本操作
下面介绍下从任务中得到其计算法返回的结果。
static void Main(string[] args)
{
var a1 = new Task<int>(()=>TastMethod("线程01"));
a1.Start();
int result = a1.Result;
Console.WriteLine("result:" + result);
Console.ReadKey();
}
static int TastMethod(string name)
{
Console.WriteLine("线程名字:"+name+"Id:"+Thread.CurrentThread.ManagedThreadId+"是否属于线程池:"+Thread.CurrentThread.IsThreadPoolThread);
return 40;
}

这里我们声明并运行了线程01并等待结果,该任务会被放置在线程池中,并且主线程会等待,直到任务返回前一直处于阻塞状态。
其实也可以调用方法RunSynchronously()方法,使其特定运行在主线程。这是一个非常好的优化,可以避免使用线程池来执行非常短暂的操作。
三、处理任务中的异常
在异步任务中,对于异常的处理是非常重要的。
try
{
var a1 = new Task<int>(() => TastMethod("线程01",2));
a1.Start();
int result = a1.Result;
Console.WriteLine("result:" + result);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
当程序启动时,创建了一个任务并尝试同步获取任务结果。Result属性的Get部分会使当前线程等待直到该任务结束,并将异常传播给当前线程。此时通过try/catch是很容易捕获到的(需要注意AggregateExceptiont,它被封装起来,)。
int result = a1.GetAwaiter().GetResult ;
上面这种情况无需封装异常,可以使用GetAwaiter和GetResult方法来访问任务结果。
小寄语
人生短暂,我不想去追求自己看不见的,我只想抓住我能看的见的。
原创不易,给个关注。
我是阿辉,感谢您的阅读,如果对你有帮助,麻烦点赞、转发 谢谢。
C#多线程开发-任务并行库04的更多相关文章
- C#当中的多线程_任务并行库(上)
复习: 第三章内容中我们提到了三种异步编程模型,这里简单复习一下,分别如下 1.APM(异步编程模式):形如Beginxxx,Endxxx. 2.EAP(基于事件的异步编程模式):这个我们在.net中 ...
- 谈谈C#多线程开发:并行、并发与异步编程
阅读导航 一.使用Task 二.并行编程 三.线程同步 四.异步编程模型 五.多线程数据安全 六.异常处理 概述 现代程序开发过程中不可避免会使用到多线程相关的技术,之所以要使用多线程,主要原因或目的 ...
- C#当中的多线程_任务并行库(下)
4.8 处理任务中的异常 下面这个例子讨论了任务当中抛出异常,以及任务异常的获取 class Program { static void Main(string[] a ...
- C#当中的多线程_任务并行库(中)
发现自己有点懒了!也可能是越往后越难了,看书理解起来有点费劲,所以这两天就每天更新一点学习笔记吧. 4.5 将APM模式转化为任务 书上提供的三种方式 方式一: class Program ...
- Python GUI之tkinter窗口视窗教程大集合(看这篇就够了) JAVA日志的前世今生 .NET MVC采用SignalR更新在线用户数 C#多线程编程系列(五)- 使用任务并行库 C#多线程编程系列(三)- 线程同步 C#多线程编程系列(二)- 线程基础 C#多线程编程系列(一)- 简介
Python GUI之tkinter窗口视窗教程大集合(看这篇就够了) 一.前言 由于本篇文章较长,所以下面给出内容目录方便跳转阅读,当然也可以用博客页面最右侧的文章目录导航栏进行跳转查阅. 一.前言 ...
- C#多线程编程系列(五)- 使用任务并行库
目录 1.1 简介 1.2 创建任务 1.3 使用任务执行基本的操作 1.4 组合任务 1.5 将APM模式转换为任务 1.6 将EAP模式转换为任务 1.7 实现取消选项 1.8 处理任务中的异常 ...
- iOS开发常用第三方库
UI 动画 网络相关 Model 其他 数据库 缓存处理 PDF 图像浏览及处理 摄像照相视频音频处理 响应式框架 消息相关 版本新API的Demo 代码安全与密码 测试及调试 AppleWatch ...
- .NET异步程序设计之任务并行库
目录 1.简介 2.Parallel类 2.0 Parallel类简介 2.1 Parallel.For() 2.2 Parallel.ForEach() 2.3 Parallel.Invoke() ...
- DELPHI XE7 新的并行库
DELPHI XE7 的新功能列表里面增加了并行库System.Threading, System.SyncObjs. 为什么要增加新的并行库? 还是为了跨平台.以前要并行编程只能从TThread类继 ...
随机推荐
- spring 读取account-service中的值
account-service //main--resources--account-service.properties 文件位置 email.protocol=smtps email.host=s ...
- CC2B本地环境搭建步骤及部署问题解决
由于最近的项目是之前没接触过的netbeans+glassfish,记录一下最近在工作中搭建本地环境的步骤及遇到的一些问题解决方法: 1.配置java jdk 此过程中遇到一个问题就是在配置系统环境变 ...
- anyRTC SDK 5月迭代:优化自定义加密功能,让通信更安全
anyRTC SDK 5月上新,新增多种加密类型,让实时音视频通信更安全:新增移动端推流支持1080P分辨率的支持:此外还对事件上报.日志详情.数据统计.网络传输等多项功能进行了优化改进. 以下为更新 ...
- Linux下-LNMP环境搭建博客网站(全过程)
通常我们所说的LNMP是指一个网站基本的组织框架,即Linux系统支持,Nginx静态服务,Mysql数据库支持以及PHP动态编程语言支持.目前Mysql数据库被Oracle数据库分析公司收购,其创始 ...
- 我为什么选Markdown
前沿说明:Yaml Front Matter MarkDown 目录 前沿说明:Yaml Front Matter 什么是MarkDown Markdown是一种轻量级标记语言, 它允许人们使用易读易 ...
- openssl not found 离线安装的openssl问题
离线安装问题 正常我们在Linux中按照 nginx的openssl依赖都是通过 yum来安装的,但是由于一些特殊的服务器公司不让服务器连接互联网,所以就导致我们必须通过离线方式来进行安装,但是我们离 ...
- 手写Pascal解释器(一)
目录 一.编写解释器的动机 二.part1 三.part2 四.part3 一.编写解释器的动机 学习了Vue之后,我发现对字符串的处理对于编写一个程序框架来说是非常重要的,就拿Vue来说,我们使用该 ...
- Docker部署Mysql实践
前言:由于Docker部署容器时,没有指定IP,当机器重启后,容器的IP会变化,所以在创建容器的时候,最好能固定IP:同时,在Ubuntu系统中,每次执行命令,都需要root权限,命令需要加sudo标 ...
- Lab: 2FA bypass using a brute-force attack:暴力破解双重验证靶场复盘(困难级别)
靶场内容: This lab's two-factor authentication is vulnerable to brute-forcing. You have already obtained ...
- IDE快捷键的使用
ctrl+ait+l,整理代码 ctrl+atl+v,生成等号左边的类型和变量 shift+方向键,选择内容 ctrl+方向键,自己领悟.常常与shift同时使用 ctrl+alt+方向键,光标前进或 ...