首页 > 编程语言 >C#异步编程之async/await

C#异步编程之async/await

时间:2023-05-20 09:00:24浏览次数:47  
标签:异步 请求 DoSomething C# await DateTime 线程 async

https://blog.csdn.net/wulex/article/details/127380403

 

异步、多线程的区别

异步 : 属于通信的范畴,在发出消息当下不等待对方回应,便开始继续自己的任务。所以 c# 的很多 _异步_ 操作都在 io 、 socket 这些类库下面,都是通信性质的类库,

io 可以理解向系统内核发送文件数据   多线程 : 属于计算范畴,通常是关于如果利用 cpu 的空闲时间进行计算。 异步同多线程可以完美的结合,服务器开启多个线程监听前端请求,接收处理完毕后,可以异步地将数据序列化到磁盘,当然如果需要知道序列化的结果则异步处理可以等待 ( await )。
从这个例子不难知道,多线程是提高数据的计算能力,而异步则是为了提高程序的吞吐量。
异步的硬件支持 计算机硬件需要依赖中断来请求 cpu 进行计算,但是中断需要存储上下文而且耗费性能,不能频繁中断 cpu 。当进行 io 操作时,一般会在用户态上进行缓存, 这时数据在内存上,接下来 cpu 切到系统态上,让 Direct Memory Access (DMA) 完成数据传输,这时 cpu 完全不过问 io 操作,待 DMA 完成时,会将在寄存器上做标记。
异步的程序原理 异步是将程序分成几个部分,每部分由一个状态控制,最后形成一个有限状态机。

何时使用async/await

asp.net mvc中使用async/await并不能提升访问速度。但使用异步编程,可以提高响应能力(吞吐量),即使用异步方式在同一时间可以处理更多的请求。使用同步方式,线程会被耗时操作一直占用,直到耗时操作结束;使用异步方式,程序走到await关键字会立即return,释放线程,剩下的代码将放到一个回调(Task.GetAwaiter()UnsafeOnCompleted(Action)),耗时操作完成时才会回调执行。

在web服务器上, .NET Framework维护用于处理ASP.NET请求的线程池。当请求到达时,将调度线程池中的线程以处理该请求。如果以同步方式处理请求,则处理请求的线程将在处理请求时处于繁忙状态,并且该线程无法处理其他请求。
在启动时看到大量并发请求的web应用中,或具有突发负载(其中并发增长突然增加)时,使web服务器调用异步会提高应用程序的相应能力。异步请求与同步请求所需的处理时间相同。如果请求发出需要两秒时间才能完成web服务调用,则该请求将需要两秒钟,无论是同步执行还是异步执行。但是,在异步调用期间,线程在等待第一个请求完成时不会被阻止响应其他请求。因此,当有多个并发请求调用长时间运行的操作时,异步请求会组织请求队列和线程池的增长。

同步方式执行耗时任务

 public ActionResult Index()
        {
            DateTime startTime = DateTime.Now;//进入DoSomething方法前的时间
            var startThreadId = Thread.CurrentThread.ManagedThreadId;//进入DoSomething方法前的线程ID
            DoSomething();//耗时操作
            DateTime endTime = DateTime.Now;//完成DoSomething方法的时间
            var endThreadId = Thread.CurrentThread.ManagedThreadId;//完成DoSomething方法后的线程ID
            return Content($"startTime:{ startTime.ToString("yyyy-MM-dd HH:mm:ss:fff") } startThreadId:{ startThreadId }\nendTime:{ endTime.ToString("yyyy-MM-dd HH:mm:ss:fff") } endThreadId:{ endThreadId }");
        }
        /// <summary>
        /// 耗时操作
        /// </summary>
        /// <returns></returns>
        private void DoSomething()
        {
            Thread.Sleep(10000);
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

异步方式执行耗时任务

 public async Task<ActionResult> Index()
        {
            DateTime startTime = DateTime.Now;//进入DoSomething方法前的时间
            var startThreadId = Thread.CurrentThread.ManagedThreadId;//进入DoSomething方法前的线程ID
            await DoSomething();//耗时操作
            DateTime endTime = DateTime.Now;//完成DoSomething方法的时间
            var endThreadId = Thread.CurrentThread.ManagedThreadId;//完成DoSomething方法后的线程ID
            return Content($"startTime:{ startTime.ToString("yyyy-MM-dd HH:mm:ss:fff") } startThreadId:{ startThreadId }\nendTime:{ endTime.ToString("yyyy-MM-dd HH:mm:ss:fff") } endThreadId:{ endThreadId }");
        }
        /// <summary>
        /// 耗时操作
        /// </summary>
        /// <returns></returns>
        private async Task DoSomething()
        {
            await Task.Run(() => Thread.Sleep(10000));
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

上面说了那么多,那到底该不该用async/await,什么时候用他俩?

总结:

  • 对于计算密集型工作,使用多线程
  • 对于IO密集型工作,采用异步机制

标签:异步,请求,DoSomething,C#,await,DateTime,线程,async
From: https://www.cnblogs.com/chinasoft/p/17416737.html

相关文章

  • 用C试一下稀疏矩阵的快速转置
    稀疏矩阵使用三元组<行,列,数值>表示。简单起见下面代码使用固定长度的数组。structval3{intx,y,e;};structmat3{introw,col,count;val3tab[MAXCOUNT];};/*x是列,y是行,从零开始计数,row是矩阵有几行,col是有几列,count是矩阵中非零元的个数*/先随机生成......
  • 基于FPGA的Hamming编译码verilog开发实现,包括testbench测试程序
    1.算法仿真效果vivado2019.2仿真结果如下:    2.算法涉及理论知识概要        汉明码(HammingCode),是在电信领域的一种线性调试码,以发明者理查德·卫斯里·汉明的名字命名。汉明码在传输的消息流中插入验证码,当计算机存储或移动数据时,可能会产生数据位错误,以侦......
  • Create Vite App 支持 OpenTiny 啦
    大家好,我是Kagol,个人公众号:前端开源星球。一个月前,日日自新写了一篇介绍CreateViteApp开源项目的文章:基于vite4.x快速搭建开箱即用,高度可定制化模版脚手架CreateViteApp是基于esbuild+commander+ejs模板渲染进行开发脚手架,用于创建vite4.xtypescript5.xvite......
  • 记一次 Oracle 下的 SQL 优化过程
    1.介绍事情是这样的,UAT环境的测试小伙伴向我扔来一个小bug,说是一个放大镜的查询很慢,转几分钟才出数据,我立马上开发环境试了一下,很快啊我说......
  • CNA-seq
    检测cnv的范围:1KB~几M,中值100KB杂合性缺失,位于一对同源染色体上的相同基因座位的两个等位基因中的一个(或其中部分核苷酸片段)发生缺失,与之配对的染色体上仍然存在1:在有的文献中指出cfDNA长度一般在167bp,ctDNA一般在145bp.在脑脊液中发现(ctDNA)取代在血浆中。本文对13个病人进行了......
  • 文心一言 VS 讯飞星火 VS chatgpt (18)-- 算法导论4.1 5题
    五、使用如下思想为最大子数组问题设计一个非递归的、线性时间的算法。从数组的左边界开始,由左至右处理,记录到目前为止已经处理过的最大子数组。若已知A[1..j]门的最大子数组,基于如下性质将解扩展为A[1..j+1]的最大子数组:A[1..j+1]的最大子数组要么是A[1..j]的最大子数组,要么是......
  • 【做题记录】CodeForces343D Water Tree
    题面翻译给出一棵以\(1\)为根节点的\(n\)个节点的有根树。每个点有一个权值,初始为\(0\)。\(m\)次操作。操作有\(3\)种:将点\(u\)和其子树上的所有节点的权值改为\(1\)。将点\(u\)到\(1\)的路径上的所有节点的权值改为\(0\)。询问点\(u\)的权值。\(1\le......
  • [ARC114D] Moving Pieces on Line 解题报告
    AT题面简要题意有一个红色的数轴,相邻两个整点之间连有一条边,所有边初始为红色。数轴上有\(n\)个棋子,将一个棋子从\(a\)位置移到\(b\)位置,可以将\((a,b)\)之间红边变为蓝边,蓝边变为红边。给定\(k-1\)条线段,问能否进行若干次操作,使得当\(i\)是奇数,第\(i\)条线段是蓝......
  • wgcloud安装部署需要什么环境
    首先WGCLOUD监控系统可以部署到Linux,也可以部署到Windows上不管是部署到Linux,还是Winodws,它依赖的环境组件都一样的1、server所在主机需要JDK1.8环境(JDK11也可以),OpenJDK也可以的,更高版本JDK也支持,但推荐JDK1.8或112、server还需要数据库来存贮数据支持MySQL、MariaDB、PostgreSQL、......
  • 云原生之使用docker部署TestLink测试平台
    (云原生之使用docker部署TestLink测试平台)一、TestLink介绍TestLink是基于web的测试用例管理系统,主要功能是测试用例的创建、管理和执行,并且还提供了一些简单的统计功能。二、TestLink的特点测试需求管理测试用例管理测试用例对测试需求的覆盖管理测试计划的制......