为了账号安全,请及时绑定邮箱和手机立即绑定

C# Async / Await 异步的一些问题

C# Async / Await 异步的一些问题

C#
凤凰求蛊 2018-06-24 13:11:27
问题1,async/await + Task.Run 与 async/await一路到底(或者说从下至上)有什么区别?   static void Main(string[] args)         {             DoSomeThingAsync();             Console.ReadLine();         }        static async void DoSomeThingAsync()         {            var users = await Task.Run(() =>             {                return GetList("aa");             });            //输出             users.ForEach(u => {                 Console.WriteLine(u.NickName);             });         }        static List<User> GetList(string name)         {            //Thread.Sleep(2000);             var result= new List<User>() {                new User() {                     NickName="aaa1"                 },                new User() {                     NickName="aaa2"                 },             };            return result;         }在我看来async/await + Task.Run或许更好,假如我的api项目是分了很多层,有interface,service,common等等... 用async/await + Task.Run的方式我只需在controller,async action,Task.Run(),而不需要去从上至下都改成async/await。 问题2,web api本来就是多线程了,为什么还要使用async/await
查看完整描述

1 回答

?
慕无忌1623718

TA贡献1744条经验 获得超4个赞

首先要知道async await解决了什么问题,不要为了异步而异步,针对高密集的cpu计算异步没太大意义,甚至可能有性能损耗。

其次说async await的实现,就以你的代码为例,如果没有async await的话代码执行步骤就不说了,在有async await后就不一样,一旦调用一个async方法,就是告知,这里我可能需要点时间来处理,你先继续往后走吧(比如io操作),这块执行线程就会继续往后跑而不再关心async方法的返回直到看到对应的await后,就停下来等着await对应的task执行完(你async await的代码在编译后会变成一个状态机,这个你可以看下你这段代码在il中的实现),执行完后就会从对应的task展开(unwarp)拿到原始结果(比如你代码中几个await的地方),这里额外就可以回答你第Task和async await的差异,async await的表现是基于Task,但显式的Task会根据TaskScheduler启动线程,而async await不会额外新起线程,async await会从当前可用线程中找空闲的线程来执行,由于所有线程都没闲着(没有所谓的等待,特别是耗时的io等待),因此服务的吞吐量会高很多(适用于高io场景)

其实上面也解释了多线程和async await的差异了,多线程不等同于异步,你拿TaskFactory或者ThreadPool搞一堆线程,它们都做着同步的工作还是会在执行的时候阻塞,线程大量的时间就这样白白浪费在了等待响应上了。


查看完整回答
反对 回复 2018-08-14
  • 1 回答
  • 0 关注
  • 774 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信