C#并发编程之异步编程(一)

简介: C#并发编程之异步编程(一)写在前面      C#5.0中,对异步编程进行了一次革命性的重构,引入了async和await这两个关键字,使得开发人员在不需要深刻了解异步编程的底层原理,就可以写出十分优美而又代码量极少的代码。

C#并发编程之异步编程(一)

写在前面

      C#5.0中,对异步编程进行了一次革命性的重构,引入了async和await这两个关键字,使得开发人员在不需要深刻了解异步编程的底层原理,就可以写出十分优美而又代码量极少的代码。如果使用得当,你可以写出具有并行化并且性能较高的程序,但是同时也增加了对异步编程理解的复杂度,毕竟在C#5.0里,你已经看不到异步编程具体是如何实现的了,需要花费额外的经历去研究探索。

      使用异步编程,使得我们释放了启动它的线程,也使得资源的占有量下降。更重要的是,有些特殊线程,比如UI线程,在运行的时候只能启动一个,如果没有快速响应,页面将会出现卡顿现象。本文只会基于.NET FX4.5及以后的版本进行讲解,之前的版本如果要实现异步编程,需要从nuget上面下载Microsoft.Bcl.Async,不过我还是建议你,如果想要在系统中大量使用编写异步代码,还是要是使用.NET FX4.5或更高的版本

      异步编程主要分为基于事件的异步模式(EAP)和基于任务的编程模式(TAP)。EAP在调用方法之前立即注册事件,它具有void返回类型,但这种模式比较混乱,它将原本的一个方法分拆成两个方法。本系列主要关注TAP编程而不涉及EAP编程。

异步编程是什么

异步关键字

      作为C#5.0中新增的重量级功能,异步功能是指程序在进行长时间操作完成后,需要继续执行的操作的一种方法,在编程过程中,会感觉这些异步代码和同步或者阻塞代码类似,但是实际上,编译器会将标识为异步的方法进行进一步的转换,是的代码可以实现真正的异步编程。它主要以两个关键字的形式功能大家使用:

  • async
  • await
 以下以一个通过EF Core查询用户信息的代码片段,这个例子没有什么特殊的地方
复制代码
public Users GetUserInfo(string userId)
{
    using (UserDbContext db = new UserDbContext())
    {
        var user = db.Users.FirstOrDefault(p => p.UserId = userId);
        return user;
    }
}
复制代码

   接下来我们看看异步的实现代码

复制代码
public async Task<Users> GetUserInfoAsync(string userId)
{
    using (UserDbContext db = new UserDbContext())
    {
        var user = await db.Users.FirstOrDefaultAsync(p => p.UserId = userId);
        return user;
    }
}
复制代码

      以上两段代码看起来非常的类似,但是仔细看却有明显的不同。异步方法上多了一个async的标识,同时返回值User,被标识成了Task<Users>,同时在进行数据库查询的时候,使用到了await。这里提前说一下await关键字,当编译器看到await关键字的时候,会截断方法,便于线程调度。简单点说,就是当调用线程运行到FirstOrDefaultAsync时,查询开始,但不是在当前线程,在新的线程里面,我们查询完数据库后,根据需要做进一步处理,比如,如果原线程UI线程,它将返回以继续处理用户的其他操作(这里非常类似回调方式),否则的话,这个线程就直接被释放了。这段可能比较抽象,会在之后的系列里进一步讲解。


为了更好的进行异步编程,我们需要在方法签名后面追加Async,这是一种异步编程的规约,也希望大家遵守。

      虽然异步编程对系统以及用户的体验非常的有帮助,但如果对异步编程不甚了解,可能会发生一些令人感到诡异的问题,而且这些问题可能通过debug方式也很难得到解决。

异步执行流程

1、想象一下,在现实世界中,一个顾客到电脑专卖店买东西,就是那种拿了就走的场景。如果店铺只有一个人,在与顾客1没有结算完成之前,对顾客2的请求,只能暂时放置一下。相信大家在现实世界中,肯定会遇到类似的情况,心情可能也很不爽,如果不是很迫切,可能是再看看,换一家店,如果比较着急,就会一直催,然后也不一定会有回应。

如下图所示

2、有一天,老板请了几个伙计帮忙搬电脑,在顾客1没有结算完成之前,老板就可以接住顾客2的需求,并通过信息系统或者大吼一嗓子的方式,让电脑准备顾客2的电脑。同时,电脑把顾客1的电脑搬到前台,由老板去跟顾客结算,整个的流程就显得体验度很高,顾客也不会被忽略,卖出去的东西也多了很多,不过等待还是要等的。

如下图所示

 

写在后面

       本文主要介绍了异步编程的基础,通过以上介绍,我们知道要创建一个异步函数,首先需要用async去修饰一个方法,同时返回值类型必须是Task或者Task<T>,当然在使用UI控制器时间处理的时候是可以使用async void的。在方法内部,需要使用await关键字。异步函数会被编译器编译成复杂的程序结构,可以视其为一种状态机。不过需要提醒的是,如果不需要编写异步函数,那就用同步。

       虽然异步编程已经变得非常简单,但是大家同样需要了解异步编程背后的理念以及原理,这有助于我们编写高性能高扩展的应用程序。


以上为本篇文章的主要内容,希望大家多提提意见,如果喜欢记得点个赞哦

原文地址https://www.cnblogs.com/edison0621/p/10542953.html

相关文章
|
4月前
|
C# 开发者
深入理解C#中的`Task<T>`:异步编程的核心
【1月更文挑战第3天】本文旨在探讨C#中`Task<T>`的使用和理解,作为异步编程模式的核心组件。`Task<T>`允许开发者在不阻塞主线程的情况下执行异步操作,并返回一个指定类型`T`的结果。通过定义返回`Task<T>`的异步方法、使用`async`和`await`关键字、处理异常以及获取任务结果,开发者可以编写出高效且响应迅速的应用程序。此外,本文还介绍了如何配置任务以及实现任务的连续性和组合,为掌握C#中的异步编程提供了全面的指导。
|
4天前
|
C# UED
C#一分钟浅谈:异步编程基础 (async/await)
在现代软件开发中,异步编程对于提升应用性能和响应性至关重要,尤其是在处理网络请求和文件读 异步编程允许程序在等待操作完成时继续执行其他任务,从而提高用户体验、高效利用资源,并增强并发性。在 C# 中,`async` 用于标记可能包含异步操作的方法,而 `await` 则用于等待异步操作完成。 示例代码展示了如何使用 `async` 和 `await` 下载文件而不阻塞调用线程。此外,本文还讨论了常见问题及解决方案,如不在 UI 线程上阻塞、避免同步上下文捕获以及正确处理异常。
18 0
|
C#
C#异步编程
C#异步编程
181 0
|
C#
c#异步编程
c#异步编程原理,await asnyc的使用方法。异步编程是指在程序执行过程中,不需要等待某个操作完成,就可以继续执行后续的代码。
292 0
|
C#
C#网络应用编程,实验七: 异步编程练习
C#网络应用编程,实验七: 异步编程练习
116 1
C#网络应用编程,实验七: 异步编程练习
|
C#
C#网络应用编程,异步编程基础练习
C#网络应用编程,异步编程基础练习
143 1
C#网络应用编程,异步编程基础练习
|
SQL 开发框架 .NET
C#5.0-原生异步编程方式
微软提供的最新的异步编程基础设施。它允许我们以模块化的方式设计程序,来组合不同的异步操作。
111 0
C#5.0-原生异步编程方式
|
Java .NET C#
C#并发编程之异步编程(线程讨论)
C#并发编程之异步编程(线程讨论)写在前面本篇是异步编程系列的第三篇,本来计划第三篇的内容是介绍异步编程中常用的几个方法,但是前两篇写出来后,身边的朋友总是会有其他问题,所以决定在续写一篇,作为异步编程(一)和异步编程(二)的补充。
1445 0
|
C# 编译器 数据库
C#并发编程之异步编程(二)
C#并发编程之异步编程(二)写在前面前面一篇文章介绍了异步编程的基本内容,同时也简要说明了async和await的一些用法。本篇文章将对async和await这两个关键字进行深入探讨,研究其中的运行机制,实现编码效率与运行效率的提升。
1411 0