HTML5技术

C#与C++的发展历程第三 - C#5.0异步编程巅峰 - hystar(7)

字号+ 作者:H5之家 来源:博客园 2016-01-15 10:03 我要评论( )

其实搞成一个状态机的目的主要还是考虑到可能存在多个await的情况。对于只有1个await的情况其实状态机的必要性不大,几个if也就够了,下面扩展下上面的例子看看有2个以上await(1个和2个await的状态机都是使用if/el

其实搞成一个状态机的目的主要还是考虑到可能存在多个await的情况。对于只有1个await的情况其实状态机的必要性不大,几个if也就够了,下面扩展下上面的例子看看有2个以上await(1个和2个await的状态机都是使用if/else解决问题,从3个起开始不同)时编译器产生的代码,首先是扩展后的C#代码(以WPF应用为例):

public partial class MainWindow : Window {     public MainWindow()     {         InitializeComponent();     }     private async void Button_Click(object sender, RoutedEventArgs e)     {         var userService = new Service();         Debug.Write(Thread.CurrentThread.ManagedThreadId);         var avatar = await userService.GetUserAvatarAsync(1);         Debug.Write(Thread.CurrentThread.ManagedThreadId);         //使用获取的avatar     } } public class Service {     private readonly Repository _repository;     private readonly WebHepler _webHelpler;     private readonly ImageLib _imgLib;     public Service()     {         _repository = new Repository();         _webHelpler = new WebHepler();         _imgLib = new ImageLib();     }     public async Task<byte[]> GetUserAvatarAsync(int id)     {         Debug.WriteLine("Service--" + Thread.CurrentThread.ManagedThreadId);         var user = await _repository.GetByIdAsync(id);         Debug.WriteLine("Service--" + Thread.CurrentThread.ManagedThreadId);         var email = user.Email;         var avatar = await _webHelpler.GetAvatarByEmailAsync(email);         Debug.WriteLine("Service--" + Thread.CurrentThread.ManagedThreadId);         var thumbnail = await _imgLib.GetImgThumbnailAsync(avatar);                  return thumbnail;     } } public class Repository {     private readonly DbContext _dbContext;     private readonly DbSet<User> _set;     public Repository()     {         //_dbContext = new DbContext("");         //_set = _dbContext.Set<User>();     }     public async Task<User> GetByIdAsync(int id)     {         Debug.WriteLine("Repo--" + Thread.CurrentThread.ManagedThreadId);         //IO...         var user = await _set.FindAsync(id);         Debug.WriteLine("Repo--" + Thread.CurrentThread.ManagedThreadId);         return user;     } } public class WebHepler {     private readonly HttpClient _httpClient;     public WebHepler()     {         _httpClient = new HttpClient();     }     public async Task<byte[]> GetAvatarByEmailAsync(string email)     {         Debug.WriteLine("Http--" + Thread.CurrentThread.ManagedThreadId);         var url = "http://avater-service-sample/" + email;         var resp = await _httpClient.GetByteArrayAsync(url);         Debug.WriteLine("Http--" + Thread.CurrentThread.ManagedThreadId);         return resp;     } } public class ImageLib {     public async Task<byte[]> GetImgThumbnailAsync(byte[] avatar)     {         //模拟一个异步图像处理任务         return await Task.Run(() =>         {             Task.Delay(500);             return avatar;         });     } }

依然以Service类为例来分析await编译后的样子:

Service中的GetUserAvatar方法中的3个await将把函数体分割为4个异步区间,如下:

图6

编译生成的代码最主要的不同是生成的状态机变了,依旧是通过截图和注释来说一下这个新的状态机的执行情况(方便对比,注释将只标出与之前状态机不同的部分):

图7

通过上面的分析,async/await关键字背后的秘密已经清清楚楚。下面来说一下线程的问题。

 

线程!

关于async/await模式线程的问题,刚开始学习async/await那阵,看到很多文章,各种各样的说法,一度让我很迷惑。

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • 2年前端学习历程,与找不到工作的悲愤与吐槽!(100%真实经历,看博主怎么一步步走向失业) - 蒋启钲

    2年前端学习历程,与找不到工作的悲愤与吐槽!(100%真实经历,看博

    2017-03-29 11:00

  • 开源第三方登录组件OAuthLogin2.0 支持QQ,阿里巴巴,淘宝,京东,蘑菇街,有赞等平台 - 大壮他哥

    开源第三方登录组件OAuthLogin2.0 支持QQ,阿里巴巴,淘宝,京东,蘑菇街

    2017-01-20 15:00

  • 从零到百亿互联网金融架构发展史 - 纯洁的微笑

    从零到百亿互联网金融架构发展史 - 纯洁的微笑

    2017-01-14 13:00

  • 记一次企业级爬虫系统升级改造(四):爬取微信公众号文章(通过搜狗与新榜等第三方平台) - 彩色铅笔

    记一次企业级爬虫系统升级改造(四):爬取微信公众号文章(通过搜狗

    2017-01-12 10:01

网友点评
r