首页 > 其他分享 >.NETCore 中的 await 原理浅析

.NETCore 中的 await 原理浅析

时间:2024-08-21 09:26:22浏览次数:12  
标签:异步 Task NETCore await 线程 操作 上下文 浅析

在.NET Core中,await 关键字是异步编程的重要组成部分,它极大地简化了异步代码的编写和维护。下面将对 await 的原理进行浅析:

目录

一、异步编程的背景

二、await 关键字的作用

三、await 的工作原理

四、注意事项


一、异步编程的背景

随着网络应用的普及和硬件性能的不断提升,I/O密集型操作(如数据库访问、网络请求等)在程序中所占比例越来越大。这类操作通常比计算密集型操作耗时更长,如果采用传统的同步编程模型,会浪费大量的计算资源并导致应用程序响应缓慢。因此,异步编程成为了一种重要的编程范式,它允许程序在等待I/O操作完成时继续执行其他任务,从而提高应用程序的吞吐量和响应能力。

二、await 关键字的作用

在.NET Core中,await 关键字用于等待一个异步操作完成。当在一个标记为 async 的方法中使用 await 时,编译器会进行一系列转换,以支持异步操作。具体来说,await 的作用包括:

  1. 上下文捕获await 会捕获当前的“上下文”(如 SynchronizationContext 或 TaskScheduler),这通常是UI线程或ASP.NET请求上下文。这个上下文对于确保异步操作完成后代码能在正确的线程上继续执行至关重要。

  2. 任务调度await 表达式后面的操作(通常是一个 Task 或 Task<T> 对象)被调度到线程池中的一个线程上执行。如果操作尚未完成,当前方法会立即返回,不会等待操作完成。

  3. 挂起与恢复:一旦异步操作完成,之前被 await 挂起的方法会在之前捕获的上下文中恢复执行。这意味着,如果 await 是在UI线程上调用的,那么操作完成后代码将继续在UI线程上执行,这对于更新UI控件非常重要。

  4. 返回值处理:如果 await 的表达式是一个 Task<T>,那么 await 会返回 T 类型的值。如果是一个 Task,则 await 会忽略返回值。

三、await 的工作原理

当程序执行到 await 语句时,会发生以下几步操作:

  1. 编译器转换:编译器会将包含 await 的方法转换为状态机,该方法在执行到 await 时会暂停,并在异步操作完成时恢复执行。

  2. 上下文传递await 会捕获当前的上下文(如UI线程上下文),并在异步操作完成后将控制权返回给该上下文,以确保后续操作在正确的线程上执行。

  3. 任务调度与执行await 后面的任务(Task 或 Task<T>)会被调度到线程池中的一个线程上执行。当前方法会在任务完成时恢复执行,或者在任务执行期间继续执行其他操作。

四、注意事项

  1. 异常处理await 表达式会抛出由它所等待的异步操作产生的任何异常。因此,可以使用 try-catch 块来捕获和处理这些异常。

  2. 性能开销:虽然异步编程能够提高应用程序的响应能力和吞吐量,但上下文切换和线程池的使用也可能导致一定的性能开销。因此,在性能敏感的场景中需要谨慎使用异步编程。

  3. 返回值类型:异步方法的返回类型通常为 TaskTask<T> 或 void。其中,void 类型主要用于事件处理程序等“触发并忘记”的场景;而 Task 和 Task<T> 则允许通过 await 等待异步操作完成并获取结果。

综上所述,await 是.NET Core中异步编程的重要组成部分,它通过简化异步代码的编写和维护,提高了应用程序的性能和响应能力。理解 await 的工作原理和注意事项,对于开发高性能、高响应能力的应用程序至关重要。

标签:异步,Task,NETCore,await,线程,操作,上下文,浅析
From: https://blog.csdn.net/x1234w4321/article/details/140817201

相关文章

  • async await 状态机理解
    publicasyncTask<string>Wait3S(){awaitTask.Delay(3000);Console.WriteLine("Wait3S");return"";}#region异步任务-状态机#iftrueTestClasstestClass=newTestClass();//调用testClass的Wait3S方法执行varWait3S=t......
  • Xilinx资源浅析之移位寄存器,BRAM,URAM
    移位寄存器SRLC32Eram_based_shifter Xilinx系列FPGA硬核IP,能够有效对移位寄存器进行处理,节省LUT资源1,移位寄存器两种基本数据流1、动态读操作(移位长度不固定)(1)输出Q由5位地址决定(2)每当一个新地址到达时,在经过访问LUT的时间延迟后,输出Q变化(3)读操作是异步的,独立于时钟......
  • 026、Vue3+TypeScript基础,使用async和await来异步读取axios的网络图片
    01、App.vue代码如下:<template><divclass="app"><h2>App.Vue</h2><Person/></div></template><scriptlang="ts"setupname="App">//JS或TSimportPersonfrom'./......
  • 第1篇:aspnetcore,webapi项目打包发布,以.net7为例
    1.打包项目,打开visualstudio项目是ChenShiBao.AspNetCore7.0,发布成功并上传服务,启动服务以这个ChenShiBao.AspNetCore7.0.dll为准1.1生成发布包1.2选择发布形式2.在终端利用scp指令将本地已发布的应用传到linux服务上,【或通过第三方工具xshell上传发布包】终端命令:scp......
  • Dubbo源码浅析(一)—RPC框架与Dubbo
    一、什么是RPC1.1RPC概念RPC,RemoteProcedureCall即远程过程调用,与之相对的是本地服务调用,即LPC(LocalProcedureCall)。本地服务调用比较常用,像我们应用内部程序**(注意此处是程序而不是方法,程序包含方法)**互相调用即为本地过程调用,而远程过程调用是指在本地调取远程过......
  • nuxt2 优化asyncData 里多个接口await串行请求的弊端,改为并行请求
    优化前多个接口await串行请求,若一个接口用时1秒,3个接口一共得用时3秒才行asyncasyncData(){letres1=awaitdanielService.getAllDanielByIndex();letres2=awaitjournalService.getJournalType();letparams={page:1,pagesize:10,......
  • 浅析house of cat(下)
    前言:这篇是hosueofcat系列的最后一篇,之后估计要停一段时间去学apple1,个人感觉学习的顺序应该是orange->apple2->cat->emma->apple1但是实际上学到cat应该就可以通杀了。但是本着学习的态度,还是看看apple1。外一以后需要用上呢。例题:这里选的例题是2022强网杯的hou......
  • 浅析house of cat(上)
    前言原本以为只学习houseofapple2就足以应对所有高版本了,但是还是被白名单制裁了,这里浅析一下houseofcat以弥补apple2的缺陷。houseofcat预计分三个部分来讲解,这篇是源码原理分析。中篇主要讲解源码调试和一些在本篇里没有讲解到的小细节绕过,下篇主要讲解例题。我个人......
  • MySQL8.0 Clone Plugin 实现解析浅析
    MySQL8.0ClonePlugin实现解析浅析从8.0.17版本开始官方实现了clone的功能,允许用户通过简单的SQL命令把远端/本地的数据库实例拷贝到其他实例后快速拉起一个新的实例。该功能由一些列的WL组成:Clonelocalreplica(WL#9209):实现了数据本地Clone。Cloneremotereplica......
  • C#多线程并发编程深度探索:解锁async、await、Task与lock等关键字的奥秘
    一、多线程介绍1.什么是多线程多线程是指在一个应用程序中同时执行多个线程的能力。每个线程都是独立运行的,拥有自己的执行路径和资源。多线程编程能够充分利用多核处理器的计算能力,提高应用程序的性能和响应性,特别是在处理耗时任务和并行计算时效果显著。在C#中,线程是程序......