线程与Task的区别 async和await关键字

任务Task和线程Thread的区别:
1、任务是架构在线程之上的,也就是说任务最终还是要抛给线程去执行。
2、任务跟线程不是一对一的关系,比如开10个任务并不是说会开10个线程,这一点任务有点类似线程池,但是任务相比线程池有很小的开销和精确的控制。
Task和Thread一样,位于System.Threading命名空间下!

使用async和await关键字。
async: 当一个方法由async关键字标识,表明这个方法是异步方法,当它被调用时,会创建一个线程来执行。
async 只能修饰用于返回void,Task,Task<>的方法。
async在VS11后不能作为程序的入口点,即Main方法不能使用async修饰符。await修饰符只能用于返回Task的方法。
async和await这两个关键字由编译器转换为状态机,通过System.Threading.Tasks中的类实现异步编程。即async和await关键字只是编译器的功能。编译器最终会用Task类创建代码。

很多文档包括msdn都刻意提到async/await关键字不会创建新的线程,用async关键字写的函数中的代码都在调用线程中执行。这里是最容易混淆的地方,严格意义上这个说法不准确,异步编程必然是多线程的。**msdn文档里提到的不会创建新线程是指async函数本身不会直接在新线程中运行。**通过反编译分析,我们知道本质上是await调用的异步函数执行完成后回调状态机的MoveNext来执行余下未执行完成的代码,await调用的异步函数必然在某个地方——也许是嵌套了很深的一个地方——启动了一个新的工作线程?来完成导致我们要使用异步调用的耗时比较长的工作,比如网络内容读取。

异步方法的返回类型必须为 void、Task、Task 中的其中一种。

void,表示无返回值,不关心异步方法执行后的结果,一般用于仅仅执行某一项任务,但是不关心结果的场景。
Task,表示异步方法将返回一个 Task 对象,该对象通常用于判断异步任务是否已经完成,可以使用 taskObj.Wait() 方法等待,或者 taskObj.IsCompleted 判断。
Task,表示异步方法将返回一个 Task 对象,该对象的 Result 属性则是异步方法的执行结果,调用该属性时将阻塞当前线程(异步方法未执行完成时)。

在使用async/await关键字时,应该遵循一些最佳实践,以提高代码的可读性、可维护性和性能。下面是一些常见的最佳实践:

  1. 尽可能将异步方法声明为TaskTask<TResult>类型,以便可以使用await关键字等待其完成。如果异步方法不返回任何内容,则应将其声明为Task类型。

  2. 在异步方法内部尽可能避免使用阻塞线程的操作,而应该使用非阻塞操作来模拟延迟。如果必须执行阻塞操作,可以将其放在不同的线程上执行,或者使用异步IO操作来避免阻塞线程。

  3. 在异步方法内部不要捕获异常并立即处理,因为这会导致代码变得复杂难以维护。应该让调用者自行处理异常。如果必须在异步方法内部捕获异常,也应该将其包装成AggregateException异常,并将其传递给调用者。

  4. 在使用ConfigureAwait(false)方法时要小心,只有在确定不需要返回到原始的SynchronizationContext上时才使用,否则可能会导致调用者无法正确处理结果。

  5. 尽量避免在异步方法中使用不安全的线程API,例如Thread.SleepThread.Join等方法,以确保代码的可移植性和稳定性。应该使用非阻塞的异步方法来模拟延迟。

  6. 在使用async/await关键字时,应该遵循一些命名约定,例如异步方法的名称应该以Async结尾,以便于区分同步和异步方法。

  7. 在需要同时等待多个异步任务完成时,可以使用Task.WhenAll方法等待所有任务完成。如果只需要等待其中一个任务完成,则可以使用Task.WhenAny方法等待任意一个任务完成。

  8. 在异步方法内部,应该将耗时的操作封装为另外的异步方法,并在需要的地方使用async/await关键字调用它们,以提高代码的可读性和可维护性。

  9. 在使用async/await关键字时,应该尽可能避免使用线程同步机制,例如lock关键字或Monitor类,因为这会导致UI线程被阻塞。而应该使用异步锁或其他非阻塞的线程同步机制。

总之,使用Task和async/await可以大大简化异步编程,提高代码的可读性、可维护性和性能。但是,需要注意一些细节和最佳实践,以确保代码的正确性和稳定性。

                        
原文链接:https://blog.csdn.net/u014677109/article/details/117407617

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/805872.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++初阶---vector(STL)

1、vector的介绍和使用 1.1、vector的介绍 1. vector是表示可变大小数组的序列容器。 2. 就像数组一样&#xff0c;vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素 进行访问&#xff0c;和数组一样高效。但是又不像数组&#xff0c;它的大小是…

为什么你选择成为一名程序员?

成为一名程序员&#xff0c;是基于多种因素的考量。 首先&#xff0c;对技术和创新的热爱是关键因素之一。编程是一种创造的过程&#xff0c;能够将抽象的想法转化为实际的应用程序和系统&#xff0c;这种创造的满足感令人着迷。 其次&#xff0c;编程领域的广阔发展前景也是…

MATLAB 普通场景的道路点云分割 (方法一)(56)

MATLAB 普通场景的道路点云分割(方法一) (56) 一、分割原理二、算法实现1.代码一、分割原理 基于这样一个认识:大部分情况下,点云都是分块去处理的,在某块点云场景中,点云区域不大,地面基本是水平分布的,不会有较大的坡度,因此将其认为是一个法向与Z轴大致平行的平…

前端开发语言种类说明

前端开发主要涉及的语言包括HTML、CSS、JavaScript&#xff0c;以及TypeScript和JQuery等流行工具和框架。这些语言和技术的详细介绍如下&#xff1a;12 HTML&#xff08;HyperText Markup Language&#xff09;。HTML是用于构建Web页面的标记语言&#xff0c;用于定义页面的结…

Python空间分析简明教程

数据世界是一个活生生的、会呼吸的事物。 当一个城市的犯罪率上升时&#xff0c;这是因为现实世界中有人在某个地方犯罪。 有警察局、住宅区和商业区、人口密度以及可以与位置相关联的人的地方。 所有这些东西都存在于数据框和表格之外的世界中。 空间分析使数据科学家能够回答…

实战环境-Activiti7从入门到专家(4)

背景 对于activiti7 已经有了感性认知&#xff0c;并且已经获得了源代码&#xff0c;梳理了核心的API。后面还有大量的内容&#xff0c;包括BPMN规范的落地&#xff0c;但是我们不能只停留在理论层次&#xff0c;需要从实际罗德的内容展开&#xff0c;因此需要构建实战环境。 …

WD西部数据正式通知客户:HDD与NAND继续涨价!

人工智能&#xff08;AI&#xff09;市场的快速增长引发了对数据存储的巨大需求。加之去年因市场环境因素导致HDD制造商减产&#xff0c;自去年下半年以来&#xff0c;高容量HDD供不应求&#xff0c;致使整体HDD价格显著上涨。据TechNews援引的行业消息指出&#xff0c;自去年第…

【测试开发学习历程】python高阶函数

目录 1 map()函数 2 reduce()函数 3 filter()函数 4 sorted()函数 1 map()函数 map()函数语法&#xff1a;map(function,iterable) 参数&#xff1a; function&#xff1a;函数 iterable&#xff1a;一个或多个序列 返回值&#xff1a;迭代器对象 作用&#xff1a;map(…

[每日算法 - 阿里机试] leetcode739. 每日温度

入口 力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台备战技术面试&#xff1f;力扣提供海量技术面试资源&#xff0c;帮助你高效提升编程技能&#xff0c;轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/daily-temperatures/descr…

定义一个函数:将输入字符串中最长的单词输出

#include <stdio.h> #include <string.h> int main(){ // 定义一个函数&#xff0c;用于判断字符是否为字母 int ab(char); // 定义一个函数&#xff0c;用于返回字符串中连续字母的最大长度起始位置 int lg(char[]); int i; char str[100…

windows安装charles抓包iphone

安装charles抓包iphone charles基础介绍windows安装 charles基础介绍 Charles 是在 PC 端常用的网络封包截取工具&#xff0c;在做移动开发时&#xff0c;我们为了调试与服务器端的网络通讯协议&#xff0c;常常需要截取网络封包来分析。除了在做移动开发中调试端口外&#xf…

不允许在constexpr函数中进行声明

这是我用pycharm在windows系统下复现sfm深度学习网络(Deep Two-View Structure-from-Motion Revisited&#xff09;遇见的问题&#xff0c;复现时有段代码pytorch扩展cuda/c&#xff0c;pycharm中出现C标准相关的报错如下&#xff1a; 在网上查找很久无果&#xff0c;后面通过…

strlen的模拟实现详解(三种办法)

文章目录 概要整体架构流程代码实现小结 概要 通过指针的运用和递归函数通过三种办法模拟实现strlen的功能 整体架构流程 第一种&#xff1a;&#xff08;计数器版&#xff09;通过指针的计算字符串的长度&#xff0c;通过while循环条件是指针不等于\0&#xff0c;来实现指针…

sipp单机压测freeswitch第4篇压测点对点呼叫

SIPp压测点对点呼叫&#xff0c;主要是使用官方提供的g711a.pcap模拟语音发起&#xff0c;在呼叫成功后Freeswitch播放一个音频文件可以是wav,SIPp后续开启Rtp回显功能&#xff0c;模拟双方相互发言 audioCall脚本xml 脚本大概意思是&#xff1a;发起成功后执行5分钟后自己挂断…

关于VMware虚拟机支不支持睿频技术的讨论

文章目录 概要名词解释超线程技术睿频技术虚拟化技术 整体测试流程测试平台 小结 概要 最近一直在研究基于Linux的虚拟机&#xff0c;目前看起来效果比在Windows上略差点&#xff0c;还没找到原因。我偶然发现在VMware这个虚拟机OS上CPU频率不对&#xff0c;我在疑惑这对于虚拟…

nginx配置实例-高可用主备模式

目录 什么是高可用&#xff1f; 解决的问题&#xff1f; 双机热备方案 keepalived是什么&#xff1f; 故障转移机制 环境准备 一、实现过程 1.1安装keepalived 安装好以后&#xff0c;将keepalived程序开启&#xff0c;并且加入到开机启动项中 1.2修改主机&#xff08;…

winform入门篇3 -- 手工创建窗口

手工创建窗口 Form, 窗口 可以手工创建一个窗口类 class MyFrom : Form { } 1.创建一个windows 窗体应用 这样就自动创建了一个窗体应用Form1 现在不使用这个自动创建的&#xff0c;手工写一个 2.手动创建 1.删除Form1.cs 2.添加 新建MyForm 类 让该类继承Form 在构造…

Covalent Network(CQT)推出以太坊质押迁移计划,以增强长期结构化数据可用性、塑造万亿级 LLM 参数体系

作为 Web3 领先的链上数据层&#xff0c;Covalent Network&#xff08;CQT&#xff09;宣布了其将质押操作从 Moonbeam 迁移回以太坊的决定。此举是 Covalent Network&#xff08;CQT&#xff09;走向以太坊时光机&#xff08;EWM&#xff09;的第一步&#xff0c;EWM 是一个为…

Python | 超前滞后分析

Nino SST Indices (Nino 12, 3, 3.4, 4; ONI and TNI) 有几个指标用于监测热带太平洋&#xff0c;所有这些指标都是基于海表温度(SST)异常在一个给定的区域的平均值。通常&#xff0c;异常是相对于30年的周期来计算的。厄尔尼诺3.4指数(Nio 3.4 index)和海洋厄尔尼诺指数(Ocea…

Qt C++ 实现文件监视源码

以下是使用Qt C++实现文件监视的一个简单示例代码: #include <QCoreApplication> #include <QFileSystemWatcher> #include <QDebug>int main(int argc, char *argv[