c# 非阻塞算法_c#关于异步编程?

await和async隐藏了很多复杂的细节,不了解的话你就很难正确的理解await和async。

一般我们需要异步的地方都是在进行比较耗时的操作,比如说磁盘IO、网络IO,当你以同步的方式调用系统API进行磁盘读取或者获取网络数据的时候,你的线程会阻塞在那里等待什么事也干不了,直到操作系统从底层返回IO数据。这就是为什么会有异步模式的存在。异步模式就是说在执行耗时IO API的时候线程不等待结果而是直接返回并注册一个回调函数,当操作系统完成耗时操作的时候,调用回调函数通知你IO结果。

await和async就是为了方便我们调用异步API而生的。当你await一个异步API的时候,你的await语句就是当前函数的最后一条语句,你肯定觉得我在胡说,明明很多时候await语句后面还有代码,这是因为编译器在后面做了很多工作。每个异步API都返回的是一个Task对象,当你await异步API的时候你就能获得这个Task对象。这个Task对象所代表的就是我上面说的那个异步模式的回调函数。Task对象有个函数叫ContinueWith,他接受的参数是一个delegate(delegate代表的就是某一个函数),ContinueWith的意思就是说当前Task对象代表的函数执行完后,继续执行ContinueWith注册进去的delegate。编译器就是将await语句后面的代码抽出来变成了另外一个函数,并用ContinueWith注册进await返回的那个Task对象。

所以总的流程就是,当你await一个异步API的时候,返回一个代表第二段所说的回调函数的Task对象,并将await之后的代码注册进Task对象,当前函数就执行完了立即返回,这个时候底层操作系统还在帮你进行费时的IO操作还没拿到结果,但你的函数已经返回上层调用了。当操作系统完成IO后,他就会回调那个Task对象,于是你的await指令后面的代码也就随之执行了。你仔细观察就会发现你执行await时候的线程ID和await之后代码的线程ID是不一样的,说明是两个不同的线程执行的代码,await之后代码是用一种叫做IO线程来执行的,await之前的线程叫做worker线程。关于IO线程和worker线程可以参考老赵的文章:浅谈线程池(上):线程池的作用及CLR线程池 - Jeffrey Zhao - 博客园

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值