C# 使用Task执行异步操作
- 为什么要使用 Task
- Task 和 Thread 区别
- Task 介绍
- Task 简单实现
- Task 执行状态
为什么要使用 Task
线程是创建并发的底层工具,因此具有一定的局限性。
- 没有简单的方法可以从联合(Join)线程得到“返回值”。因此必须创建一些共享域。当抛出一个异常时,捕捉和处理异常也是麻烦的。
- 线程完成之后,无法再次启动该线程。相反,只能联合(Join)它(在进程阻塞当前线程)。
任务是可组合的——使用延续将它们串联在一起。它们可以使用线程池减少启动延迟,而且它们可以通过TaskCompletionSource
使用回调方法,避免多个线程同时等待I/O密集操作。
Task 和 Thread 区别
1、任务是架构在线程之上的,也就是说任务最终还是要抛给线程去执行。
2、任务跟线程不是一对一的关系,比如开10个任务并不是说会开10个线程,这一点任务有点类似线程池,但是任务相比线程池有很小的开销和精确的控制。
Task和Thread一样,位于System.Threading命名空间下
与线程相比,Task
是一个更高级的抽象概念,它标识一个通过或不通过线程实现的并发操作。
Task 介绍
Task 类的表示单个操作不返回一个值,通常以异步方式执行。 Task 对象是一个的中心思想 基于任务的异步模式 首次引入.NET Framework 4 中。 因为由执行工作 Task 对象通常以异步方式执行在线程池线程上而不是以同步方式在主应用程序线程,您可以使用 Status 属性,以及 IsCanceled, ,IsCompleted, ,和 IsFaulted 属性,以确定任务的状态。 大多数情况下,lambda 表达式用于指定的任务是执行的工作。
Task 简单实现
通过使用Task的构造函数来创建任务,并调用Start方法来启动任务并执行异步操作。
static void Main(string[] args)
{
Console.WriteLine("主线程执行业务处理.");
//创建任务
Task task = new Task(() => {
Console.WriteLine("使用System.Threading.Tasks.Task执行异步操作.");
for (int i = ; i < ; i++)
{
Console.WriteLine(i);
}
});
//启动任务,并安排到当前任务队列线程中执行任务
task.Start();
Console.WriteLine("主线程执行其他处理");
}
从Framework 4.5开始,启动一个由后台线程实现的Task,也可以使用静态方法 Task.Run
Task task = Task.Run(() =>
{
Thread.Sleep();
Console.WriteLine("Foo");
});
Task默认使用线程池,它们都是后台线程。意味当主线程结束时,所有任务都会随之停止。
Task 执行状态
1.等待(Wait)
调用Wait
方法,可以阻塞任务,直至任务完成,效果等同于Thread.Join
:
Task task = Task.Run(() =>
{
Thread.Sleep();
Console.WriteLine("Foo");
});
Console.WriteLine(task.IsCompleted); //False
task.Wait();//阻塞,直至任务完成
Console.WriteLine(task.IsCompleted); //True
Console.ReadLine();
2. 返回值
Task<TResult>
允许任务返回一个值。调用Task.Run
,传入一个Func<TResult>
代理(或者兼容的Lambda表达式),代替Action,就可以获得一个Task<TResult>:
Task<int> task = Task.Run (() => { Console.WriteLine ("Foo"); return ; }); int result = task.Result; // Blocks if not already finished
Console.WriteLine (result); //
下面的例子创建一个任务,它使用LINQ就按前3百万个整数(从2开始)中的素数个数:
Task<int> primeNumberTask = Task.Run(() =>
Enumerable.Range(, ).Count(n => Enumerable.Range(, (int)Math.Sqrt(n) - ).All(i => n % i > ))); Console.WriteLine("Task running...");
Console.WriteLine("The answer is " + primeNumberTask.Result);
这段代码会打印“Task running...”,然后几秒钟后打印216815。
3. Task.Delay
Task.Delay
是Thread.Sleep
的异步版本
Task.Delay().GetAwaiter().OnCompleted(()=>Console.WriteLine());
或者
Task.Delay().ContinueWith(ant => Console.WriteLine());
参考资料:
https://www.jianshu.com/p/4444f2d77f3b
https://www.cnblogs.com/pengstone/archive/2012/12/23/2830238.html
C# 使用Task执行异步操作的更多相关文章
- C# 线程知识--使用Task执行异步操作
在C#4.0之前需要执行一个复杂的异步操作时,只能使用CLR线程池技术来执行一个任务.线程池执行异步任务时,不知道任务何时完成,以及任务的在任务完成后不能获取到返回值.但是在C#4.0中引人了一个的任 ...
- C#执行异步操作的几种方式比较和总结
C#执行异步操作的几种方式比较和总结 0x00 引言 之前写程序的时候在遇到一些比较花时间的操作例如HTTP请求时,总是会new一个Thread处理.对XxxxxAsync()之类的方法也没去了解过, ...
- [C#] 走进异步编程的世界 - 在 GUI 中执行异步操作
走进异步编程的世界 - 在 GUI 中执行异步操作 [博主]反骨仔 [原文地址]http://www.cnblogs.com/liqingwen/p/5877042.html 序 这是继<开始接 ...
- C#执行异步操作的几种方式比较和总结(转发:https://www.cnblogs.com/durow/p/4826653.html)
0x00 引言 之前写程序的时候在遇到一些比较花时间的操作例如HTTP请求时,总是会new一个Thread处理.对XxxxxAsync()之类的方法也没去了解过,倒也没遇到什么大问题.最近因为需求要求 ...
- 走进异步编程的世界 - 在 GUI 中执行异步操作
转载:https://www.cnblogs.com/liqingwen/p/5877042.html 走进异步编程的世界 - 在 GUI 中执行异步操作 [博主]反骨仔 [原文地址]http://w ...
- C# 线程知识--使用ThreadPool执行异步操作
C# 线程知识--使用ThreadPool执行异步操作 在应用程序中有许多复杂的任务,对于这些任务可能需要使用一个或多个工作线程或I/O线程来协作处理,比如:定时任务.数据库数据操作.web服务.文件 ...
- .NET 并行(多核)编程系列之五 Task执行和异常处理
原文:.NET 并行(多核)编程系列之五 Task执行和异常处理 .NET 并行(多核)编程系列之五 Task执行和异常处理 前言:本篇主要讲述等待task执行完成. 本篇的议题如下: 1. 等待Ta ...
- 【Spark2.0源码学习】-10.Task执行与回馈
通过上一节内容,DriverEndpoint最终生成多个可执行的TaskDescription对象,并向各个ExecutorEndpoint发送LaunchTask指令,本节内容将关注Exe ...
- [Spark内核] 第37课:Task执行内幕与结果处理解密
本课主题 Task执行内幕与结果处理解密 引言 这一章我们主要关心的是 Task 是怎样被计算的以及结果是怎么被处理的 了解 Task 是怎样被计算的以及结果是怎么被处理的 Task 执行原理流程图 ...
随机推荐
- extern "C" 分析 -转
1.引言 C++语言的创建初衷是“a better C”,但是这并不意味着C++中类似C语言的全局变量和函数所采用的编译和连接方式与C语言完全相同.作为一种欲与C兼容的语言,C++保留了一部分过程式语 ...
- C++——调用优化
原始代码 #include<iostream> using namespace std; class Test { public: //以参数列表形式对数据成员进行初始化 Test() : ...
- Springboot分别使用乐观锁和分布式锁(基于redisson)完成高并发防超卖
原文 :https://blog.csdn.net/tianyaleixiaowu/article/details/90036180 乐观锁 乐观锁就是在修改时,带上version版本号.这样如果试图 ...
- Spring Boot 2发送邮件手把手图文教程
原文:http://www.itmuch.com/spring-boot/send-email/ 本文基于:Spring Boot 2.1.3,理论支持Spring Boot 2.x所有版本. 最近有 ...
- django实现发送邮件功能
django实现邮件发送功能 1)首先注册一个邮箱,这里以163邮箱为例 2)注册之后登录,进行如下修改 找到设置,设置一个授权码,授权码的目的仅仅是让你有权限发邮件,但是不能登录到邮箱进行修改,发送 ...
- MySQL进阶12-- 数据类型介绍: 数值型/字符型/日期型-- 正负溢出保护/枚举型/set型/时间戳
/*进阶12 SQL 数据类型介绍 数值型: 整数: Tinyint(1b) < mediumint(3b)<smallint(2b) <int(4b) <bigint(8b) ...
- export default 和 export 的使用方式
node中导入模块:var 名称 = require('模块标识符') node中向外暴露成员的形式:module.exports = {} 在ES6中,也通过规范的形式,规定了ES6中如何导入和导出 ...
- 17 webpack中babel的配置
在webpack中,默认只能处理一部分ES6的新语法,一些更高级的ES6语法或者ES7语法, webpack是处理不了的:这时候,就需要借助于第三方的loader,来帮助webpack处理这些高级的语 ...
- UML类图介绍
一.概述 UML类图用来定义系统中的类,包括描述类的结构和类之间的关系.类图的主要作用于描述系统的静态结构. 类图的基本模型元素如下:
- DNS工作流程及原理 域名、IP与DNS的关系
转自:http://blog.csdn.net/maminyao/article/details/7390208 一.DNS服务概述 DNS是Domain Name System的缩写,即域名系统.其 ...