写在前面

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关键字。异步函数会被编译器编译成复杂的程序结构,可以视其为一种状态机。不过需要提醒的是,如果不需要编写异步函数,那就用同步。

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

【憩园】C#并发编程之异步编程(一)的更多相关文章

  1. C#并发编程之异步编程2

    C#并发编程之异步编程(二)   写在前面 前面一篇文章介绍了异步编程的基本内容,同时也简要说明了async和await的一些用法.本篇文章将对async和await这两个关键字进行深入探讨,研究其中 ...

  2. C#复习笔记(5)--C#5:简化的异步编程(异步编程的基础知识)

    异步编程的基础知识 C#5推出的async和await关键字使异步编程从表面上来说变得简单了许多,我们只需要了解不多的知识就可以编写出有效的异步代码. 在介绍async和await之前,先介绍一些基础 ...

  3. .NET “底层”异步编程模式——异步编程模型(Asynchronous Programming Model,APM)

    本文内容 异步编程类型 异步编程模型(APM) 参考资料 首先澄清,异步编程模式(Asynchronous Programming Patterns)与异步编程模型(Asynchronous Prog ...

  4. 【憩园】C#并发编程之异步编程(三)

      写在前面 本篇是异步编程系列的第三篇,本来计划第三篇的内容是介绍异步编程中常用的几个方法,但是前两篇写出来后,身边的朋友总是会有其他问题,所以决定再续写一篇,作为异步编程(一)和异步编程(二)的补 ...

  5. 【憩园】C#并发编程之异步编程(二)

    写在前面 前面一篇文章介绍了异步编程的基本内容,同时也简要说明了async和await的一些用法.本篇文章将对async和await这两个关键字进行深入探讨,研究其中的运行机制,实现编码效率与运行效率 ...

  6. 关于如何提高Web服务端并发效率的异步编程技术

    最近我研究技术的一个重点是java的多线程开发,在我早期学习java的时候,很多书上把java的多线程开发标榜为简单易用,这个简单易用是以C语言作为参照的,不过我也没有使用过C语言开发过多线程,我只知 ...

  7. 如何提高Web服务端并发效率的异步编程技术

    作为一名web工程师都希望自己做的web应用能被越来越多的人使用,如果我们所做的web应用随着用户的增多而宕机了,那么越来越多的人就会变得越来越少了,为了让我们的web应用能有更多人使用,我们就得提升 ...

  8. Java网络编程中异步编程的理解

    目录 前言 一.异步,同步,阻塞和非阻塞的理解 二.异步编程从用户层面和框架层面不同角度的理解 用户角度的理解 框架角度的理解 三.为什么使用异步 四.理解这些能在实际中的应用 六.困惑 参考文章 前 ...

  9. C#复习笔记(5)--C#5:简化的异步编程(异步编程的深入分析)

    首先,阐明一下标题的这个“深入分析”起得很惭愧,但是又不知道该起什么名字,这个系列也主要是做一些复习的笔记,供自己以后查阅,如果能够帮助到别人,那自然是再好不过了. 然后,我想说的是异步方法的状态机真 ...

随机推荐

  1. PuppeteerSharp: 更友好的 Headless Chrome C# API

    前端就有了对 headless 浏览器的需求,最多的应用场景有两个 UI 自动化测试:摆脱手工浏览点击页面确认功能模式 爬虫:解决页面内容异步加载等问题 也就有了很多杰出的实现,前端经常使用的莫过于 ...

  2. mapbox.gl源码解析——基本架构与数据渲染流程

    加载地图 Mapbox GL JS是一个JavaScript库,使用WebGL渲染交互式矢量瓦片地图和栅格瓦片地图.WebGL渲染意味着高性能,MapboxGL能够渲染大量的地图要素,拥有流畅的交互以 ...

  3. eggjs 框架代理调试 SELF_SIGNED_CERT_IN_CHAIN 报错解决方案

    eggjs 中的 this.ctx.curl 可以发起一个请求,配置 proxy 可以很方面的通过接口进行问题定位.代理方式如下: 1.开启 egg-development-proxyagent ,配 ...

  4. 吴恩达机器学习笔记60-大规模机器学习(Large Scale Machine Learning)

    一.随机梯度下降算法 之前了解的梯度下降是指批量梯度下降:如果我们一定需要一个大规模的训练集,我们可以尝试使用随机梯度下降法(SGD)来代替批量梯度下降法. 在随机梯度下降法中,我们定义代价函数为一个 ...

  5. web服务器,验证码,Xftp使用方法

    IIS操作步骤 直接装的wamp 腾讯云主机控制台 安全组里可以配置要开放的端口 关闭防火墙 (C:\wamp\bin\apache\Apache2.4.4) 打开httpd.conf文件 requi ...

  6. C# ListView 控件和 INotifyPropertyChanged 接口

    ListView 控件和 DataGridView 控件 ListView 是跟 Winform 中 DataGridView 用法以及显示效果差不多的一个 WPF 控件,可以通过列表的方式方便的显示 ...

  7. MySQL命令窗口下中文显示乱码的解决过程

    在dos客户端输出窗口中查询表中的数据,还有项目部署到服务器上时前台的页面,中文数据都显示成乱码,如下图所示: 这个问题困扰了我一天,后来解决了才发现原来我的方向错了,一直我以为是SpringBoot ...

  8. Android or Java的回调粗俗理解 这才是最通俗易懂的

    FUCK,网上装逼者甚众矣! 网上一堆关于JAVA函数回调的见解文章,都说自己写的明白,但没几个我看的明白的. 不如自己写一个东西,回头自己看着舒服 回调函数:定义自己百度 干嘛的? 场景就是事务A执 ...

  9. 从壹开始微服务 [ DDD ] 之四 ║让你明白DDD的小故事 & EFCore初探

    缘起 哈喽大家好哟,今天又到了老张的周二四放送时间了,当然中间还有不定期的更新(因为个人看papi酱看多了),这个主要是针对小伙伴提出的问题和优秀解决方案而写的,经过上周两篇DDD领域驱动设计的试水, ...

  10. matplotlib安装

    Windows / Linux pip 相关依赖 Python (>= 2.7 or >= 3.4) NumPy (>= 1.7.1) setuptools dateutil (&g ...