C#异步编程之async/await

C#中await/async用法 看微软的官方文档看的头大,比较晦涩的,反正我是啃不动,这里通俗的解释一下c# 中的await/async说白了await/async就是一个语法糖,单纯使用await/async并不会创建一个线程,创建线程的这个操作由是线程池决定的。那么我们为啥还要使用await/async呢?答:为了更好的编写异步操作,也就是识别性更高 可以看到,单纯在方... 阅读详情

异步编程场景

解决耗时任务占用主线程执行的问题。因此耗时高的任务适用于异步编程,C#中有以下场景:

  1. 对于 I/O 绑定代码,等待一个在 async 方法中返回 Task 或 Task<T> 的操作。
  2. 对于 CPU 绑定代码,等待一个使用 Task.Run 方法在后台线程启动的操作。

如何判断是CPU耗时操作还是IO耗时操作呢?简单来说,如果需要等待某些内容(如数据库中的数据、大文本文件的读取等),则为IO耗时操作;如果需要执行大量的计算,则属于CPU耗时操作。

async await

async/await成对出现,用于简化异步编程。async出现在方法的声明前,表示这是一个异步方法。await则出现在这个异步方法的内部,一般在Task前。
async/await关键字本身不会创建新线程,但被await的方法内部一般是通过创建线程来实现。

微软官方给定的异步方法执行顺序:
在这里插入图片描述

到底异步还是同步?

这个标题算是个问题?问题又不太对。async/await成对出现的方法是异步方法,那哪来的同步呢?实际上最好先从多线程说起,关于异步编程这块,我准备整理一个系列出来。顺序上可能是这篇博客先出来,那就用下面的例子先展示一下。

我看到有的文章说,async/await既可以是异步,又可以是同步。所以就会有疑惑,到底是同步还是异步呢?看下面两个例子。

异步方式执行

两个Task输出并没有按顺序,且并没有按主线程中代码顺序来执行。可以看到,两个异步方法尚未输出完成,主方法中main end.....已经输出。且Method1和Method2中的输出也是交替来的。
输出结果:
在这里插入图片描述

static void Main()
{
    Console.WriteLine("main start....");
    AsyncMethod1();
    AsyncMethod2();
    Thread.Sleep(1000);
    Console.WriteLine("main end.....");
    Console.ReadLine();
}
static async void AsyncMethod1()
{
    Console.WriteLine("start AsyncMethod1 async");
    var result = await MyMethod1();
    Console.WriteLine("end AsyncMethod1 async");
}
static async Task<int> MyMethod1()
{
    for(int i = 0; i < 5; i++)
    {
        Console.WriteLine("Async MyMethod1 start:" + i.ToString());
        await Task.Delay(1000);
    }
    return 0;
}
static async void AsyncMethod2()
{
    Console.WriteLine("start AsyncMethod2 async");
    var result = await MyMethod2();
    Console.WriteLine("end AsyncMethod2 async");
}
static async Task<int> MyMethod2()
{
    for(int i = 0; i < 5; i++)
    {
        Console.WriteLine("Async MyMethod2 start:" + i.ToString());
        await Task.Delay(1000);
    }
    return 0;
}
异步方法同步执行

结合上面那个例子,再看这个例子的输出,就容易理解所谓的异步方法同步执行了。意思是说,Method1和Method2两个方法是异步执行的(理解成创建一个新线程去执行的吧)。但是,通过一些手段,让这两个任务按顺序来执行。即Method1执行完再来执行Method2。

两个Task相对主线程来说,是异步去执行的,但这个异步也是按顺序来的。Method1输出完了,再执行Method2的输出。
在这里插入图片描述

static void Main()
{
    Console.WriteLine("Async Test job");
    Console.WriteLine("main start.....");
    Console.WriteLine("MyMethod() 异步方法同步执行:");
    int i = MyMethod().GetAwaiter().GetResult();
    int j = MyMethod2().GetAwaiter().GetResult();
    
    Console.WriteLine($" i : {i}");
    Console.WriteLine($" j : {j}");
    Console.WriteLine("main end .....");
    Console.ReadLine();
}
static async Task<int> MyMethod()
{
    for(int i = 0; i < 5; i++)
    {
        Console.WriteLine("Async Method start: " + i.ToString());
        await Task.Delay(1000);
    }
    return 0;
}
static async Task<int> MyMethod2()
{
    for(int i = 0; i < 5; i++)
    {
        Console.WriteLine("Async Method2 start: " + i.ToString());
        await Task.Delay(1000);
    }
    return 0;
}

何时使用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);
        }
异步方式执行耗时任务
 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));
        }

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

总结:

  • 对于计算密集型工作,使用多线程
  • 对于IO密集型工作,采用异步机制
C#中的async和await的使用详解 C#中的async和await的使用 在C#中,在很多的时候,都需要一些异步操作,并且在做完这些异步操作之后,可以在后面接着做一些处理,在 .net framework 4.5之后,便加入了一种简洁的方式来使用异步操作,这就是async和await。 async用来声明一个函数体,将其声明为异步方法,而await则是用在这个函数体的内部,用于等待一个异步操作的完成。 异步方法内部可以出现一个或者多个await,一般不要是0个,这样就失去了异步方法的意义了。 ... 阅读详情

相关推荐

C# 异步之Async/await

该文章仅为个人理解,如有错误请指正,标红内容为重点,会有针对异步的多个文章,包含Task,APM(BeginInvoke,EndInvoke)等。 一、基本概念: Async/await 关键字是在.Net 4.5引入的关键字来创建自动延续任务实现异步调用。 async/await是语法糖,等价于task.Run().ContinueWith(action,Task.FromCurrentS...

窝。。。 2089

C# async / await 用法

await 运算符暂停对其所属的 async 方法的求值,直到其操作数表示的异步操作完成。异步操作完成后,await 运算符将返回操作的结果(如果有)。当 await 运算符应用到表示已完成操作的操作数时,它将立即返回操作的结果,而不会暂停其所属的方法。await 运算符不会阻止计算异步方法的线程。当 await 运算符暂停其所属的异步方法时,控件将返回到方法的调用方。下面来做一个演示,点击按钮1开始启动异步,点击按钮2,就返回结果,如果不点击按钮2,那么异步一直在循环中。

熊思雨的博客 2万+

C#异步编程 async/await

C#的async/await是基于 Task 的语法糖,本质上不引入新的多线程机制,而是简化异步编程模型,让异步代码像同步代码一样简洁易读。async用于修饰方法,await用于等待异步操作,需配合使用。适用于I/O密集型任务(如网络请求、文件操作)和UI交互场景,不适合CPU密集型计算

qq_34552942的博客 969

C#异步编程(async和await)

异步编程的核心是Task和Task对象,这两个对象对异步操作建模。它们受关键字async和await的支持。在大多数情况下模型十分简单:对于 I/O 绑定代码,等待一个在async方法中返回Task或Task的操作。对于 CPU 绑定代码,等待一个使用Task.Run方法在后台线程启动的操作。通过使用异步编程,可以避免性能瓶颈并增强应用程序的总体响应能力。但是,编写异步应用程序的传统技术可能比较复杂,使它们难以编写、调试和维护。C# 5 引入了一种简便方法,即异步编程。

风清扬的专栏 8742

C# 异步编程async/await

异步这个概念在不同语境下有不同的解释,比如在一个单核CPU里开启两个线程执行两个函数,通常认为这种调用是异步的,但对于CPU来说它是单核不可能同时运行两个函数,不过是由系统调度在不同的时间分片中执行。一般来说,如果两个工作能同时进行,就认为是异步的。在编程中,它通常代表函数的调用可以在不执行完的情况下返回,必要时在完成时回调。有一个概念常常被混淆,多线程和异步。

xxxzzzqqq_的博客 1489

C# 异步编程详解(Task,async/await)

同步和异步主要用于修饰方法。当一个方法被调用时,调用者需要等待该方法执行完毕并返回才能继续执行,我们称这个方法是同步方法;当一个方法被调用时立即返回,并获取一个线程执行该方法内部的业务,调用者不用等待该方法执行完毕,我们称这个方法为异步方法。异步的好处在于非阻塞(调用线程不会暂停执行去等待子线程完成),因此我们把一些不需要立即使用结果、较耗时的任务设为异步执行,可以提高程序的运行效率。

luxingyu329的博客 4153

C# 中的Async 和 Await 的用法详解

在这里,我们使用异步编程从文件中读取所有内容,所以它不会等待从这个方法获得一个返回值并执行其他代码行,但是它必须等待下面给出的代码行,因为我们使用的是等待关键字,我们将对下面给出的代码行使用返回值。我们将创建一个新的方法,作为CallMethod,在这个方法中,我们将调用我们的所有方法,分别为Method1、Method2和Method3。在这里,在传递Method3中的参数之前,我们必须使用AWAIT关键字,为此,我们必须使用调用方法中的async关键字。在这种情况下,异步编程将非常有用。...

weixin_41883890的博客 1万+

c#异步编程(async/await)

c# sync/await

积累点滴,保持自我 1169

C# async/await 异步编程

/ 异步操作// 模拟耗时操作C# 中的异步编程通过async和await关键字实现,能够显著提高程序的响应性和性能。它特别适用于 I/O 密集型操作、UI 应用程序和 Web 应用程序等场景。通过合理使用异步编程,可以编写出高效、简洁且易于维护的代码。

malaopang的博客 1233

C#异步编程实战:Task与async/await的高效应用指南

本文深入探讨C#异步编程的核心机制,重点解析Task与async/await的高效应用。通过实战示例,详细讲解Task的创建、等待、延续、取消与异常处理,以及async/await如何简化异步代码编写。文章还提供了避免死锁、优化性能的实战避坑指南,帮助开发者提升应用程序的响应速度与资源利用率。

weixin_29302047的博客 617

告别龟速!实测Copernicus Dataspace下载Sentinel-2数据的3个提速技巧(附Workspace批量操作)

本文分享了在Copernicus Dataspace平台高效下载Sentinel-2遥感数据的3个实用技巧,包括网络传输层优化、浏览器与API调优以及Workspace批量操作。通过这些方法,用户可将下载速度提升300%以上,特别适合科研人员和团队处理大规模数据需求。

weixin_30706691的博客 178

C# async/await异步编程

C# async/await异步编程前言异步方法的结构调用异步方法异步方法本体耗时函数`async`/`await`异步函数的原理示例代码的执行流程带返回值的异步函数死锁这样没省多少事啊?参考: 前言 Talk is cheap, Show you the code first! 先上代码: private void button1_Click(object sender, EventArgs e) { Console.WriteLine("111 balabala. My Thread ID is

天富儿的博客 1649

软考软件评测师备考避坑指南:过来人告诉你这5个章节最容易丢分(附2024最新考纲解析)

本文为软考软件评测师考生提供备考避坑指南,深度解析5个高频失分章节,包括标准化与信息化基础、中间件技术、软件测试模型、白盒测试覆盖准则和性能测试指标。文章结合2024最新考纲,分享实战技巧和记忆口诀,帮助考生精准打击失分重灾区,提升备考效率。

weixin_29223603的博客 467

C#中的async/await彻底改变异步编程模式

随着云原生和微服务架构的普及,高效处理并发和异步操作的能力将变得愈加重要,而async/await作为C#异步编程的基石,必将在这一过程中发挥关键作用。首先,异步方法命名约定建议方法名以Async后缀结尾,这清晰表明了方法的异步特性,方便开发者识别和使用。开发者可以使用熟悉的try/catch块来捕获异步操作中的异常,就像处理同步代码一样自然,这大大提高了异步代码的可靠性。这一语法糖彻底改变了开发者编写异步代码的方式,使得异步代码在结构上和同步代码几乎一样简洁明了,大大降低了异步编程的理解和实现门槛。

Steve_ke的博客 926

使用Gromacs进行蛋白和配体小分子的动力学模拟+结果分析全流程教程

先选protein,选择non-water,使用pymol打开delWater.pdb,输入util.ss('all')展示cartoon,点击file-Export Moive as-MPEG。这一步完成后,文件夹中会出现以下三个文件,其中gro 文件用于记录蛋白的初始坐标,top 文件记录蛋白的拓扑信息和力场信息,itp 与top文件类似。接下来使用Spdbv软件打开蛋白,如果蛋白中存在原子缺失情况,就会出现以下的提示,如果不存在就不会显示,同时保存为rep.pdb。

weixin_46587777的博客 2853

Win11网络卡顿?用Wireshark抓包5分钟定位问题(保姆级实战)

本文详细介绍了如何使用Wireshark在Win11系统中快速定位网络卡顿问题。通过5分钟抓包分析,作者成功发现TCP重传率高达37%的罪魁祸首,并提供了从准备工作到实战分析的保姆级教程,帮助用户解决游戏卡顿、视频会议延迟等常见网络问题。

weixin_28839629的博客 306

探索C#异步编程从Task到async/await的全面解析

Task作为.NET 4.0引入的核心异步编程模型,代表了异步操作的抽象概念。通过Task.Run方法,可以轻松将同步代码转换为异步执行,同时Task.Status属性提供了对任务状态的实时监控能力,包括Created、WaitingForActivation、Running和Completed等状态值。异常处理方面,应当使用try-catch块包装await表达式,因为异步方法的异常会存储在返回的Task对象中。async/await关键字的引入是C# 5.0的重大革新,它极大简化了异步编程的复杂性。

技术派做新零售创业 744

128、点云配准与ICP:经典配准算法与深度学习配准

上周调试一台双臂协作机器人,左手持结构光相机扫描桌面上的随机堆叠工件,右手准备执行抓取。问题出在“对齐”这一步——相机扫描得到的点云和CAD模型点云之间差了大约15度的旋转,导致抓取姿态计算出来直接怼到桌面上。我第一反应是“ICP跑一下不就行了”,结果跑了三分钟,误差纹丝不动,甚至越迭代越发散。后来查了日志才发现,初始位姿给得太离谱,ICP直接掉进了局部最优。这个场景太典型了——很多人以为点云配准就是调个ICP库函数,实际工程里坑比想象中多得多。今天这篇笔记,咱们把点云配准这件事从头捋一遍。

sundong_81的博客 42

深入浅出 C# 异步编程:掌握 async/await 的最佳实践

在同步编程中,执行的每个任务都会阻塞当前线程,直到任务完成。而在异步编程中,任务在等待时不会阻塞线程,其他任务可以继续执行,直到被等待的任务完成。这种非阻塞的执行方式,使得应用程序能够在处理 I/O 密集型操作时保持响应性,从而提高用户体验和系统性能。Console.WriteLine("异步任务开始");// 调用异步方法Console.WriteLine("异步任务完成");// 使用 async 关键字标记方法为异步方法Console.WriteLine("开始执行异步任务...")

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 2798

计算机视觉(角点检测)- 1 - Harris角点检测

计算机视觉(角点检测)-1.1 Harris角点检测学习前言 学习前言   今天更新一下计算机视觉的东西吧,哈哈哈o( ̄︶ ̄)o   关于角点检测呢,就是检测图像中角点的算法,常见的有四种常见的算法:Moravec角点检测算法、 Harris角点检测算法、Shi-Tomasi 算法、FAST角点检测算法,不过常用的就两种吧——Harris角点检测算法、Shi-Tomasi 算法(反正我基本上就只用到这两种,先着重介绍前面两种,后面再花世界介绍吧)(~ ̄▽ ̄)~ ...

qq_40374812的博客 1万+

安全监控:人员行为分析_(2).人员行为分析基础理论

人员行为分析是指利用计算机视觉技术对视频中的人类行为进行实时或离线检测、识别和理解的过程。视频采集:通过摄像头等设备获取视频数据。视频预处理:对视频数据进行噪声过滤、图像增强等处理,以便后续分析。特征提取:从视频中提取出与人员行为相关的特征,如人体姿势、动作轨迹等。行为识别:利用机器学习或深度学习模型对提取的特征进行分类,识别出具体的人员行为。行为理解:对识别出的行为进行进一步分析,理解其背后的意图或状态。在人员行为分析中,常用的公开数据集包括UCF101、HMDB51、ActivityNet等。

zhubeibei168的博客 1345

C# 异步编程:从 async/await 到 Task 并行库的全面解析

本文全面介绍了C#异步编程的核心技术,包括async/await关键字和Task并行库。通过对比同步编程的局限性,阐述了异步编程在处理I/O密集型和CPU密集型任务时的优势。文章详细解析了async/await的使用方法,展示了Task类及其泛型版本Task<T>的基本用法,并介绍了并行任务处理的WhenAll和WhenAny方法。最后结合文件读写、网络请求等实际应用场景,说明了异步编程如何提升程序性能和响应速度。全文为开发者提供了从基础到实践的异步编程指南。

葡萄城技术团队博客 1229

私家侦探如何追踪难以找到的人,掌握几个很少人知道的在线免费查询网站,搜索人名、电话号码以及地址的开源网站

私家侦探如何追踪难以找到的人,掌握几个很少人知道的在线免费查询网站,搜索人名、电话号码以及地址的开源网站。

代码讲故事 6487

探索C#异步编程从Task到async/await的实践指南

然而,尽管TPL功能强大,使用回调式的延续仍然可能导致代码嵌套过深,难以维护,这便是async/await语法糖所要解决的核心问题。await关键字则用于挂起当前方法的执行,直到其等待的Task完成,同时将控制权返回给调用方,避免了线程的阻塞。这种机制确保了异步操作的高效性,同时极大简化了开发者需要编写的代码量,将复杂性完全隐藏在编译器生成的代码中。更重要的是,异步方法返回的Task会将异常封装在AggregateException中,或者通过await自动解包,使得调用方能够以自然的方式处理异常。

huangxiaobeng的博客 1224

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

C# 异步编程和 async/await

异步编程是一种在程序执行过程中,允许执行其他任务而不阻塞当前任务的编程模式。这对于处理需要等待的操作(例如文件 I/O、网络请求)尤为重要。

Lsss123aa的博客 656

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

上一篇: C# 后端数据验证的使用
下一篇: .net 使用Docker开发
.NET跨平台
博客等级 码龄15年 6066粉丝 738原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值