【.NET Core】深入理解async 和 await 理解

【.NET Core】深入理解async 和 await 理解

文章目录

  • 【.NET Core】深入理解async 和 await 理解
    • 一、概述
    • 二、async异步执行机制理解
    • 三、`async`与`await`应用
      • 3.1 `async`与`await`简单应用
      • 3.2 带有返回值`async`与`await`应用
    • 四、`async`和`await`中常见问题总结
      • 4.1 当方法用async标识时,编译器主要做了什么?
      • 4.2 当方法用async标识时,是不是所有调用者都将是异步?
      • 4.3 当方法用async标识时,是否会引起方法的调用会被添加到线程池队列中或者是创建一个新的线程呢?
      • 4.4 参数为什么不能使用ref和out关键字
      • 4.5 await关键字背后发生了什么
  • 五、总结

在这里插入图片描述

一、概述

asyncawait是C#5.0时代引入异步编程的核心关键字。通过使用异步编程,你可以避免性能瓶颈并增强程序响应能力。但是,编写异步应用程序的传统技术可能比较复杂,使异步编程难编写,调试和维护。

C#中的asyncawait关键字是异步编程的核心。通过这两个关键字,可以使用.NET Framework,.NET Core或Windows运行时中的资源,轻松创建异步方法。使用async关键字定义的异步方法简称为”异步方法“。

二、async异步执行机制理解

  • 在C#中,async标记了一个包含异步执行的函数,通过async的函数若在主线程中直接调用,则函数一开始扔在主线程中执行。
  • async标记的函数内部必须包含await标记需要异步执行的函数,若当前函数在主线程中直接调用,则await标记当前的代码在主线程中执行,await标记后的代码在其异步子线程中执行。
  • async标记的函数返回值必须为voidTaskTask<TResult>类型,可以理解为async标记的函数返回的是null,即将执行的任务带返回结果的即将执行的任务
  • async标记的函数可以继续往下调用async标记函数。

三、asyncawait应用

3.1 asyncawait简单应用

internal class Program
{static void Main(string[] args){Method1();Method2();Console.ReadKey();}public static async Task Method1(){await Task.Run(() =>{for (int i = 0; i < 30; i++){Task.Delay(100);Console.WriteLine(" Method 1");}});}public static void Method2(){for (int i = 0; i < 25; i++){Task.Delay(80);Console.WriteLine(" Method 2");}}
}

从上面代码运行结果可以看出,Method1和Method2相互并没有依赖关系,Method1和Method2并不是在等待对方完成。

3.2 带有返回值asyncawait应用

static void Main(string[] args)
{callMethod();Console.ReadKey();
}
public static async void callMethod()
{Task<int> task = Method1();Method2();int count = await task;Method3(count);
}
public static async Task<int> Method1()
{int count = 0;await Task.Run(() =>{for (int i = 0; i < 20; i++){Console.WriteLine(" Method 1");count += 1;}});return count;
}public static void Method2()
{for (int i = 0; i < 25; i++){Console.WriteLine(" Method 2");}
}
public static void Method3(int count)
{Console.WriteLine("Total count is " + count);
}

在上面给出的代码中,Method 3需要一个参数,即Method 1的返回类型。在这里,await关键字对于等待Method 1任务的完成起着至关重要的作用。

四、asyncawait中常见问题总结

4.1 当方法用async标识时,编译器主要做了什么?

  • 告诉编译器这个方法里面可能会用到await关键字来标识该方法是异步的,如此之后,编译器将会在状态机中编译此方法。接着该方法执行到await关键字时会处于挂起的状态直到该异步动作完成后才恢复继续执行方法后面的动作。
  • 告诉编译器解析出方法的结果到返回类型中,比如说Task或者Task,也就是说将返回值存储到Task中,如果返回值为void那么此时应该会将可能出现的异常存储到上下文中。

4.2 当方法用async标识时,是不是所有调用者都将是异步?

当将方法用async标识时且返回值为void或者Task或者Task,此时该方法会在当前线程中一直同步执行。

用async标识方法并不会影响方法运行完成是否是同步或者异步,相反,它能够将方法划分成多块,有可能有些在异步中运行,以至于这些方法是异步完成的,而划分异步和同步方法的边界就是使用await关键字。也就是说如果在方法中未用到await关键字时则该方法就是一整块没有所谓的划分,会在同步中运行,在同步中完成。

4.3 当方法用async标识时,是否会引起方法的调用会被添加到线程池队列中或者是创建一个新的线程呢?

显然不是这样,当用async标识方法时只是显示告诉编译器在该方法中await关键字可能会被用到,当执行到await关键字开始处于挂起的状态知道异步动作执行完成才恢复(异步操作是在状态机中【有关状态机请看这里:Async和Await异步编程的原理】完成,完成后此时才会创建一个线程),这也就是为什么在方法中方法用async标识如果没有用到await关键字IDE会发出警告的原因。

到了这里我们可以得出结论:无论方法是同步还是异步都可以用async关键字来进行标识,因为用async标识只是显示表明在该方法内可能会用到await关键字使其变为异步方法,而且将该异步方法进行了明确的划分,只有用了await关键字时才是异步操作,其余一并为同步操作。

4.4 参数为什么不能使用ref和out关键字

我们知道用ref和out关键字不过是为了在方法里面改变其值,也就是是当同步完成时我们期望被ref或者out关键字修饰的值会被设置,但是它们可能在异步完成时或者之后才会被设置达不到我们预期,所以在异步方法中不能用ref和out关键字。

4.5 await关键字背后发生了什么

await关键字是这样用的

await Task.Run(() => "goyeer");

此时背后究竟发生了什么呢?我们上述也说过异步动作时在状态机中完成,当执行到这里时,编译器会自动生成代码来检测该动作是否已经完成,如果已经完成则继续同步执行await关键字后面的代码,通过判断其状态机状态若未完成则会挂起一个继续的委托为await关键字的对象直到完成为止,调用这个继续动作的委托重新进入未完成的这样一个方法。

五、总结

本节我们详细讲述了async和await关键字的使用和一些基本原理以及解释其原因,希望通过对本文的学习,对大家能够更好的去理解异步。

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

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

相关文章

Editing While Playing 使用 Easyx 开发的 RPG 地图编辑器 tilemap eaitor

AWSD移动画布 鼠标右键长按拖拽 鼠标左键长按绘制 可以边拖拽边移动画布边绘制。 F1 导出 DLC F2 导入DLC author: 民用级脑的研发记录 1309602336qq.com 开发环境&#xff1a; 内置 easyx 的 devc 5.11 或者 VS 2022 TDM GCC 4.9.2 64-bit c11及以上都可运行 windows 环境运行…

JS加密解密之JS广告漂浮代码分析

前言 之前有个客户要求帮忙复刻一份广告漂浮代码&#xff0c;我看了下&#xff0c;目标站的广告代码是通过了JS加密后的&#xff0c;经过我解密还原后分析了一下该代码的作用如下。 ;var _0xodDddd,_0xodD_[_0xodD],_0x1d02[_0xodD,\x73\x54\x69\x6d\x65,\x6c\x6f\x61\x64\x5…

计算机专业必看的几部电影

计算机专业必看的几部电影 计算机专业必看的几部电影&#xff0c;就像一场精彩的编程盛宴&#xff01;《黑客帝国》让你穿越虚拟世界&#xff0c;感受高科技的魅力&#xff1b;《社交网络》揭示了互联网巨头的创业之路&#xff0c;《源代码》带你穿越时间解救世界&#xff0c;…

PAM | 账户安全 | 管理

PAM PAM&#xff08;Pluggable Authentication Modules&#xff0c;可插入式身份验证模块&#xff09;是一个灵活的身份验证系统&#xff0c;允许我们通过配置和组合各种模块来实现不同的身份验证策略。 在 Linux 或类 Unix 系统中&#xff0c;常见的 PAM 模块包括以下几种类…

Ansible file文件模块 设置文件的属性,比如创建文件、创建链接文件、删除文件

目录 语法创建目录创建链接文件删除文件 每个值的属性 语法 创建目录 ansible slave -m file -a path/data/app statedirectory path/data/app # 定义创建路径 statedirectory # 如果目录不存在就创建目录这就是创建目录成功之后的回显 可以看到&#xff0c;已经打印出目录a…

MySQL的基础架构

文章目录 前言MySQL的基础架构总结 前言 你使用 MySQL 开发&#xff0c;你知道 MySQL 的基础架构吗&#xff1f;本文带你来入门MySQL 的基础架构 MySQL的基础架构 MySQL 是我们经常使用到的数据库。它的基础架构分为 server 层与存储引擎层。 server 层&#xff1a;用于存储…

推荐彩虹知识付费商城免授权7.0源码

彩虹知识付费商城免授权7.0源码&#xff0c;最低配置环境 PHP7.2 1、上传源码到网站根目录&#xff0c;导入数据库文件&#xff1a;xydai.sql 2、修改数据库配置文件&#xff1a;/config.php 3、后台&#xff1a;/admin 账号&#xff1a;admin 密码&#xff1a;123456 4、前…

【Jvm】类加载机制(Class Loading Mechanism)原理及应用场景

文章目录 Jvm基本组成一.什么是JVM类的加载二.类的生命周期阶段1&#xff1a;加载阶段2&#xff1a;验证阶段3&#xff1a;准备阶段4&#xff1a;解析阶段5&#xff1a;初始化 三.类初始化时机四.类加载器1.引导类加载器&#xff08;Bootstrap Class Loader&#xff09;2.拓展类…

第九篇:node静态文件服务(中间件)

&#x1f3ac; 江城开朗的豌豆&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 &#x1f4dd; 个人网站 :《 江城开朗的豌豆&#x1fadb; 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! &#x1f4d8; 引言&#xff1a; 当今互联网时代&am…

[AIGC] 利用 ChatGpt 深入理解 Java 虚拟机(JVM)的内存分布

深入理解 Java 虚拟机&#xff08;JVM&#xff09;的内存分布 Java 虚拟机&#xff08;JVM&#xff09;是 Java 编程语言的核心运行环境&#xff0c;它负责解释和执行 Java 字节码。在 JVM 中&#xff0c;内存被划分为几个不同的区域&#xff0c;每个区域都有特定的用途。了解…

SG3225EEN晶体振荡器规格书

SG3225EEN 晶振是EPSON/爱普生的一款额定频率25 MHz至500 MHz的石英晶体振荡器&#xff0c;6脚贴片&#xff0c;LV-PECL输出&#xff0c;3225封装常规有源晶振&#xff0c;具有小尺寸&#xff0c;轻薄型&#xff0c;高稳定性&#xff0c;低相位抖动&#xff0c;低电源电压&…

anomalib1.0学习纪实-续2:三个文件夹

为了读懂程序&#xff0c;有三个最重要的文件夹&#xff0c;如下图&#xff1a; 正好对应四个类&#xff0c;如下图&#xff1a; 四个类的来源如下图所示&#xff1a; 注意&#xff0c;MVTec是个大类&#xff0c;里面用到了这里的第四个类MVTecDataset&#xff0c;代码如下。…

java以及android类加载机制

类加载机制 一、Java类加载机制 java中&#xff0c;每一个类或者接口&#xff0c;在编译后&#xff0c;都会生成一个.class文件。 类加载机制指的是将这些.class文件中的二进制数据读入到内存中并对数据进行校验&#xff0c;解析和初始化。最终&#xff0c;每一个类都会在方…

深入实战:ElasticSearch的Rest API与迭代器模式在高效查询中的应用

在我们公司&#xff0c;大多数Java开发工程师在项目中都有使用Elasticsearch的经验。通常&#xff0c;他们会通过引入第三方工具包或使用Elasticsearch Client等方式来进行数据查询。然而&#xff0c;当涉及到基于Elasticsearch Rest API的/_sql?formatjson接口时&#xff0c;…

CentOS上如何配置手动和定时任务自动进行时间同步

场景 Linux(Centos)上使用crontab实现定时任务(定时执行脚本)&#xff1a; Linux(Centos)上使用crontab实现定时任务(定时执行脚本)_centos 定时任务-CSDN博客 Winserver上如何配置和开启NTP客户端进行时间同步&#xff1a; Winserver上如何配置和开启NTP客户端进行时间同步…

motplotlib图例案例1:通过多个legend完全控制图例显示顺序(指定按行排序 or 按列排序)

这个方法的核心&#xff0c;是手动的获得图中的handlers和labels&#xff0c;然后对它们进行切分和提取&#xff0c;最后分为几个legend进行显示。代码如下&#xff1a; 后来对下面的代码进行修改&#xff0c;通过handlers, labels get_legend_handles_labels(axs[axis])自动的…

Unity所有关于旋转的方法详解

前言&#xff1a;欧拉角和四元数的简单描述 我们在Inspector面板上看到的rotation其实是欧拉角&#xff0c; 我们将Inspector面板设置成Debug模式&#xff0c;此时看到的local Rotation才是四元数。 Unity中的欧拉旋转是按照Z-X-Y顺规执行的旋转&#xff0c;一组欧拉旋转过程中…

Transformer面试十问

1 Scaled Dot-Product Attention中为什么要除以 d k \sqrt{d_k} dk​ ​? 1. 从纯数学上考虑&#xff1a;对于输入均值为0,方差为1的分布&#xff0c;点乘后结果其方差为dk&#xff0c;所以需要缩放一下。下图为原论文注释。 2. 从神经网络上考虑&#xff1a;防止在计算点积…

杨氏矩阵和杨辉三角

杨氏矩阵 有一个数字矩阵&#xff0c;矩阵的每行从左到右是递增的&#xff0c;矩阵从上到下是递增的&#xff0c;请编写程序在这样的矩阵中查找某个数字是否存在。 要求&#xff1a;时间复杂度小于O(N); 分析 若要满足要求时间复杂度小于O(N)&#xff0c;就不能每一行一个个…

树和二叉树的基本知识

一、树的概念及结构 1.树的概念 树是一种 非线性 的数据结构&#xff0c;它是由 n &#xff08; n>0 &#xff09;个有限结点组成一个具有层次关系的集合。 把它叫做树是因 为它看起来像一棵倒挂的树&#xff0c;也就是说它是根朝上&#xff0c;而叶朝下的 。 有一个 特殊…