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命令详解
命令语法介绍 命令 [参数] [文件或路径] rm -f /etc/hosts 注:命令和参数至少一个空格(可以多个连着写) 路径不带空格 ...
- sql网址
w3school版 https://www.w3school.com.cn/sql/index.asp 菜鸟教程版 https://www.runoob.com/sql/sql-tutorial.ht ...
- IDEA实用教程(五)——配置IDEA的JVM内存值
---恢复内容开始--- 四. 配置IDEA的JVM内存值 IDEA默认配置的JVM内存值比较低,如果硬件配置较高,可以修改该设置. 该设置需要在工程界面进行. 该操作仅建议内存8G以上,64位操作系 ...
- puppeteer报错 UnhandledPromiseRejectionWarning: Error: Protocol error (Page.getLayoutMetrics): Target closed.
puppeteer运行时报错: UnhandledPromiseRejectionWarning: Error: Protocol error (Page.getLayoutMetrics): Tar ...
- 【Java】debug初级使用(Eclipse)
1.设置.取消断点 双击要设置断点的代码行数字的前面 2.切换成Debug界面 就会发现画面变成了下图这样 以下是调试的界面解说(图源百度) 3.切换为原界面
- 删除TOMCAT服务器上的文件
deleteFile(文件名称,路径名称); public boolean deleteFile(String filename,String filepath){ String path =Ser ...
- WebStorm 安装
官方下载地址:https://www.jetbrains.com/webstorm/ 下载 安装 等待.......... 安装完成........................ 开始使用(第一次 ...
- Vue 定义全局变量
main.js 中定义 import Ws from './lib/ws' import ElementUI from 'element-ui'; import GlobalFunc from './ ...
- 073_使用 shell 脚本打印如下图形
#!/bin/bash #打印第一组图片#for(())为类 C 语言的语法格式,也可以使用 for i in;do;done 的格式替换#for((i=1;i<=9;i++))循环会执行 9 ...
- 使用webuploader实现大文件传输
这里只写后端的代码,基本的思想就是,前端将文件分片,然后每次访问上传接口的时候,向后端传入参数:当前为第几块文件,和分片总数 下面直接贴代码吧,一些难懂的我大部分都加上注释了: 上传文件实体类: 看得 ...