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 执行原理流程图 ...
随机推荐
- Linux命令——ulimit
参考:https://www.cnblogs.com/kongzhongqijing/p/5784293.html
- IAR 为 STM32新建工程模板(最详细)
今天给小伙伴分享一篇给stm32新建工程模版 1.首先打开IAR,就是这个样子 2.再建一个目录文件夹 3.建立一个工作空间,以及建好工作空间如右图所示 4.接下来建立工程,Project------ ...
- LOJ-1308-Ant network(蚂蚁的网络)-求割点分隔开的子图个数及乘积
网上的题解大都模糊,我可能写的也比较模糊吧,讲究看看. 大致题意: 原图没有一个割点时,特殊考虑,至少ans1=2个通风井,方案数n*(n-1)/2; 原图上有多个割点时,每个(由割点限制成几部分的) ...
- 安装Genymotion模拟器(第三方)
优势: 启动速度更快 注册账户,下载可用的系统镜像,就可以使用. 官方网站: https://www.genymotion.com/account/login/ 选择的版本是带VirtualB ...
- latex 表格每行设置不同字体
Each cell of a table is set in a box, so that a change of font style (or whatever) only lasts to the ...
- Selenium常用API的使用java语言之16-下拉框选择
有时我们会碰到下拉框,WebDriver提供了Select类来处理下接框. 如百度搜索设置的下拉框,如下图: 搜索下拉框实现代码如下: <select id="nr" nam ...
- pandas 数据类型研究(一)数据转换
当利用pandas进行数据处理的时候,经常会遇到数据类型的问题,当拿到数据的时候,首先需要确定拿到的是正确类型的数据,一般通过数据类型的转化,这篇文章就介绍pandas里面的数据类型(data typ ...
- python - orm 字段
1.models.AutoField 自增列 = int(11) 如果没有的话,默认会生成一个名称为 id 的列,如果要显示的自定义一个自增列,必须将给列设置为主键 primary_key=True. ...
- HttpServletRequest获取浏览器、服务端和客户端信息
如何通过HttpServletRequest来获取到上面的属性呢? 1.引入开源工具 <!-- https://mvnrepository.com/artifact/eu.bitwalker/U ...
- 【Winfrom-无边框窗体】Winform如何拖动无边框窗体?
去掉边框 this.FormBorderStyle = FormBorderStyle.None; 方法一: Point mouseOff;//鼠标移动位置变量 bool leftFlag;//标签是 ...