C#如何使用Task执行异步操作
作者:HarryK 发布时间:2023-01-12 03:34:41
目录
为什么要使用 Task
Task 和 Thread 区别
Task 介绍
Task 简单实现
Task 执行状态
1.等待(Wait)
2. 返回值
3. Task.Delay
为什么要使用 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 = 0; i < 10; i++)
{
Console.WriteLine(i);
}
});
//启动任务,并安排到当前任务队列线程中执行任务
task.Start();
Console.WriteLine("主线程执行其他处理");
}
从Framework 4.5开始,启动一个由后台线程实现的Task,也可以使用静态方法 Task.Run
Task task = Task.Run(() =>
{
Thread.Sleep(2000);
Console.WriteLine("Foo");
});
Task默认使用线程池,它们都是后台线程。意味当主线程结束时,所有任务都会随之停止。
Task 执行状态
1.等待(Wait)
调用Wait方法,可以阻塞任务,直至任务完成,效果等同于Thread.Join:
Task task = Task.Run(() =>
{
Thread.Sleep(2000);
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 3; });
int result = task.Result; // Blocks if not already finished
Console.WriteLine (result); // 3
下面的例子创建一个任务,它使用LINQ就按前3百万个整数(从2开始)中的素数个数:
Task<int> primeNumberTask = Task.Run(() =>
Enumerable.Range(2, 3000000).Count(n => Enumerable.Range(2, (int)Math.Sqrt(n) - 1).All(i => n % i > 0)));
Console.WriteLine("Task running...");
Console.WriteLine("The answer is " + primeNumberTask.Result);
这段代码会打印“Task running...”,然后几秒钟后打印216815。
3. Task.Delay
Task.Delay是Thread.Sleep的异步版本
Task.Delay(5000).GetAwaiter().OnCompleted(()=>Console.WriteLine(42));
或者
Task.Delay(5000).ContinueWith(ant => Console.WriteLine(42));
来源:https://www.cnblogs.com/HarryK4952/p/14716829.html


猜你喜欢
- android的WebView组件可以说是相当的强大,现将项目中经常用到的几个功能总结如下:一、背景设置WebView.setBackgro
- 这几天面试中有遇到关于main数组中的args数组传值的问题,一般是从命令提示符中传值,也可以直接在java代码中赋值。而且这个数组的长度是
- 1、写在前面今天群里一个小伙伴问了这样一个问题,扩展方法与实例方法的执行顺序是什么样子的,谁先谁后(这个问题会在文章结尾回答)。所以写了这边
- 在 MyEclipse 的可视化 Swing 中,有 JTable 控件。JTable 用来显示和编辑常规二维单元表。那么,如何将 数据库S
- 首先不可否认,这些在面试上会经常被面试官问起,但是你回答的让面试官满意吗?当然如果你知道了这些原理,或许你就不怕了。既然说到了原理,我们还是
- 在逆向一个Android程序时,如果只是盲目的分析需要阅读N多代码才能找到程序的关键点或Hook点,本文将分享一下如何快速的找到APP程序的
- 一.什么是SemaphoreSemaphore,俗称信号量,它是操作系统中PV操作的原语在java的实现,它也是基于AbstractQueu
- 前言jdk中提供了许多的并发工具类,大家可能比较熟悉的有CountDownLatch,主要用来阻塞一个线程运行,直到其他线程运行完毕。而jd
- 前言Java17将是一个长期支持的LTS版本。Java采用了6个月的发布周期。也就是说,它将每6个月发布一个新版本的Java。每隔3年,LT
- 自定义View实现一个弹性滑动的效果,供大家参考,具体内容如下实现原理onMeasure()中测量所有子View @Override pro
- Android 网络请求框架Volley实例详解首先上效果图Logcat日志信息on ReponseVolley特别适合数据量不大但是通信频
- Android 倒计时一般实现方式:handler+postDelayed() 方式Timer + TimerTask + handler
- 什么是反射机制反射是java语言的一个特性,它允程序在运行时(注意不是编译的时候)来进行自我检查并且对内部的成员进行操作。例如它允许一个ja
- 前言现如今几乎大多数Java应用,例如我们耳熟能详的tomcat, struts2, netty...等等数都数不过来的软件,要满足通用性,
- 本文实例为大家分享了Java实现带图形界面聊天程序的具体代码,供大家参考,具体内容如下ServerDemo01.javaimport jav
- JDK集合源码之HashMap解析1.树结构入门1.1 什么是树?树(tree)是一种抽象数据类型(ADT),用来模拟具有树状结构性质的数据
- 本文采用C#实例讲解了处理图片为浮雕效果的实现方法,这在PS中是一个常见的功能,也是C#中的一个简单的图像处理例子。程序先读取原图,然后依次
- 1、使用场景 因为最近项目需要国际化,需要能够支持多种国际化语言,目前需要支持三种(法
- 一、场景描述仪器数据文件的格式包含Pdf、Word、Excel等多种,不同种格式的文件其数据的采集方式不同,因此定义仪器数据采集接口,并定义
- 介绍Spring Profiles 提供了一套隔离应用配置的方式,不同的 profiles 提供不同组合的配置,在不同的环境中,应用在启动时