首页 > 编程语言 >C# Async、Await原理

C# Async、Await原理

时间:2023-09-14 11:47:44浏览次数:51  
标签:异步 await C# Await Task 线程 Async 方法 Wait

1、使用异步编程需要async和await:

  • Task 任务可以使用aweit

  • 匿名方法 (包括Lambda表达式) ,通过async也可以变成异步方法

2、加async await表示这个方法可以异步顺序执行。(不加await会出现并行执行)

3、async +await函数调用不会造成阻塞,它内部所有的await阻塞都被封装在一个 异步对象中异步执行。

任务和线程的区别:
1、任务是架构在线程之上的,也就是说任务最终还是要抛给线程去执行。

2、任务跟线程不是一对一的关系,比如开10个任务并不是说会开10个线程,
这一点任务有点类似线程池,但是任务相比线程池有很小的开销和精确的控制。

  //Task.Run 本质还是开启一个线程。
  //任务是架构在线程池之上的,也就是说任务最终还是要抛给线程去执行。
  //当方法返回类型为void类型时。使用Task类型返回

优点:当程序需要大量耗时操作,如网络请求,查询数据等就需要用到Task,开启一个任务来执行。

从而避免影响主线程UI界面假死。 在任务请求过程中需要使用 aweit等待任务返回的结果。然后在执行下一步。

任务(不加aweit会出现并行执行),会导致请求的结果未拿到,就执行下面的代码,从而引发异常。

async, await 底层是状态机, 而如果返回值是void的话,调度方是不会有等待行为的,因为没有awaiter

总结一:

  • async的方法会被C#编译器编译成一个类,会主要根据await调用进行切分为多个状态,对async方法的掉用会被拆分
  • 为对MoveNext()的调用。
  • 用await看似时“等待”,经过编译后,其实没有“wait()”

总结二:

await调用的等待时间,.net会把当前的线程返回给线程池(避免占用线程,影响并发),等异步方法执行完成之后,框架会从线程池中在取得一个线程执行后续的代码。

线程池是如何分配线程的?

​ 答:当这个异步方法耗时,速度很慢时,那个线程池就会收回这个线程。当这个异步方法执行完成之后,线程池会在取一个

线程执行后续代码。 而当这个异步方法执行速度很快,那么线程池就不会收回线程。也不会分配线程。

总结三:

​ Task的方法返回值,不一定每一步都标记async , 只需要最后调用时候使用(避免async 重复拆装箱)

异步方法是怎么运作的:

C#编译器一旦遇到以async声明的方法(即异步方法)时会在这个方法中尝试寻找await关键字,如果找到以await关键字声明的方法,就会自动生成一些代码,这些代码负责启动后台线程,尝试找到空闲的CPU内核运行以await声明的方法(即以异步方式运行),完成这一切后调用者线程从异步方法返回。后台线程在运行完以await声明的方法后会结束,此时await关键字生成的代码还负责提取方法的返回结果,所以干活的都是await,async实际上只是提醒编译器"你看到有async关键字的方法时进去方法内部是不是有个await关键字,有的话就干活"。

**C# 异步 await的原理 使用了OnCompleted 回调函数 **

await是什么意思 [两层思想]

  1. Task.Wait()和await`混为一谈,这是错的
  2. await在控制异步的执行次序
  3. await有等待结果的含义
提到await,就得先说说Wait。

字面意思,Wait就是等待。

前边说了,异步有一个核心,是Task。而Task有一个方法,就是Wait,写法是Task.Wait()。所以,很多人把这个Wait和await混为一谈,这是错的。

这个问题来自于Task。C#里,Task不是专为异步准备的,它表达的是一个线程,是工作在线程池里的一个线程。异步是线程的一种应用,多线程也是线程的一种应用。Wait,以及Status、IsCanceled、IsCompleted、IsFaulted等等,是给多线程准备的方法,跟异步没有半毛钱关系。当然你非要在异步中使用多线程的Wait或其它,从代码编译层面不会出错,但程序会。

尤其,Task.Wait()是一个同步方法,用于多线程中阻塞等待。

在那个「同步方法中调用异步方法」的文章中,用Task.Wait()来实现同步方法中调用异步方法,这个用法本身就是错误的。 异步不是多线程,而且在多线程中,多个Task.Wait()使用也会死锁,也有解决和避免死锁的一整套方式。

再说一遍:Task.Wait()是一个同步方法,用于多线程中阻塞等待,不是实现同步方法中调用异步方法的实现方式。
https://www.cnblogs.com/tiger-wang/p/13357981.html

Task.Wait()是一个同步方法,用于多线程中阻塞等待,不是实现同步方法中调用异步方法的实现方式。

https://www.zhihu.com/question/58922017/answer/1358059753

标签:异步,await,C#,Await,Task,线程,Async,方法,Wait
From: https://www.cnblogs.com/kkbk/p/17702112.html

相关文章

  • React Table 表库
    ReactTableReactTable 是一个比较特别的存在。它可以说是所有表格组件中的F-22战斗机,包含天量功能,可以几乎定制无限复杂的表格需求。GitHub、亚马逊、微软、Uber的大量前端项目都在大量使用ReactTable。它的作者也是个传奇人物,不光创作了ReactTable,还有ReactQuery,......
  • 有什么巨好用Excel数据分析技巧?
    当涉及Excel数据分析时,以下是一些非常实用的技巧和功能,供您参考。这里将为您提供关于数据整理、数据清洗、统计分析、可视化和高级分析等方面的技巧。一、数据整理与清洗:导入数据:使用Excel的数据导入功能,将外部数据源(如文本文件、数据库等)导入到工作表中。数据筛选:利用Exce......
  • pytorch-多头注意力
    多头注意力在实践中,当给定相同的查询、键和值的集合时,我们希望模型可以基于相同的注意力机制学习到不同的行为,然后将不同的行为作为知识组合起来,捕获序列内各种范围的依赖关系(例如,短距离依赖和长距离依赖关系)。因此,允许注意力机制组合使用查询、键和值的不同子空间表示(represent......
  • vue-unsaved-changes-dialog 在桌面页面上,弹出窗会跟随鼠标显示
    简介及使用教程这是一个漂亮的未保存变更对话框,有以下特点:有保存、丢弃和取消三个按钮在桌面页面上,弹出窗会跟随鼠标显示显示隐藏动画流畅智能避免弹出在窗口边缘并且随窗口大小调整自动适应完全自适应:在移动设备上全屏显示键盘可导航可访问所有的文案都可以替换更......
  • 自定义内存分配在 uC/OS-II 中的应用
    uC/OS-II是一个广泛用于嵌入式系统的实时操作系统内核,它提供了强大的多任务管理和调度功能。在嵌入式应用中,内存管理是一个至关重要的问题,而uC/OS-II允许开发人员自定义内存分配策略,以满足不同应用的需求。本文将讨论在uC/OS-II中如何进行自定义内存分配,并提供相关的代码演示......
  • BOSHIDA DC电源模块在保护设备损坏的重要功能
    BOSHIDADC电源模块在保护设备损坏的重要功能DC电源模块是一种电源管理设备,用于将交流电转换为直流电并提供给设备供电。它通常由多个电子元件组成,包括整流器、滤波器、稳压器等,以确保电源输出稳定,满足设备的电源需求。 在实际应用中,DC电源模块有着非常重要的保护设备损坏的......
  • CommandLineRunner - Spring Boot应用程序启动后执行
    在springboot启动的时候,有的时候需要做一些初始化或者预加载的事情。springboot给我们提供了这样一个接口CommandLineRunnerCommandLineRunner是一个接口,用于在SpringBoot应用程序启动后执行一些特定的任务或代码块。当应用程序启动完成后,SpringBoot会查找并执行实现了Comma......
  • 基于Docker的Redis集群配置(1)
    拉取redis镜像dockerpullredis:6.0.8启动6个docker容器,名称与端口不可重复#--cluster-enabledyes#开启redis集群#--nethost#使用宿主机的IP和端口#--appendonlyyes#开启持久化#--nameredis-1 #自定义容器名字dockerrun-d--nameredis-1--networkhost......
  • Leetcode 1193. 每月交易Ⅰ
    1193.每月交易Ⅰ题目表:Transactions+---------------+---------+|ColumnName|Type|+---------------+---------+|id|int||country|varchar||state|enum||amount|int||trans_date|date......
  • 多主架构:VLDB技术论文《Taurus MM: bringing multi-master to the cloud》解读
    本文分享自华为云社区《多主创新,让云数据库性能更卓越》,作者:GaussDB数据库。华为《TaurusMM:bringingmulti-mastertothecloud》论文被国际数据库顶会VLDB2023录用,这篇论文里讲述了符合云原生数据库特点的超燃技术。介绍了如何通过各种黑科技减少云原生数据库的网络消耗,进......