首页 新闻 会员 周边 捐助

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

0
悬赏园豆:50 [已解决问题] 解决于 2017-10-24 11:43

问题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。

复制代码
  class Program
    {
        static void Main(string[] args)
        {
            DoSomeThingAsync();

            Console.ReadLine();
        }

        static async void DoSomeThingAsync()
        {
            var users = await GetList("aa");
            //输出
            users.ForEach(u => {
                Console.WriteLine(u.NickName);
            });
        }

        public static async Task<List<User>> GetList(string name)
        {
            await Task.Delay(2000);
            var result=new List<User>() {
                new User() {
                    NickName="aaa1"
                },
                new User() {
                    NickName="aaa2"
                },
            };
            return result;
        }
    }

    //接口层
    public interface IUserServices
    {
        Task<List<User>> GetListAsync(string name);
    }

    //接口实现层
    public class UserServices : IUserServices
    {
        public async Task<List<User>> GetListAsync(string name)
        {
            return await Program.GetList("aa");
        }
    }
复制代码

 问题2,web api本来就是多线程了,为什么还要使用async/await?

找不到一个满意的昵称的主页 找不到一个满意的昵称 | 菜鸟二级 | 园豆:243
提问于:2017-10-23 15:10
< >
分享
最佳答案
0

首先要知道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搞一堆线程,它们都做着同步的工作还是会在执行的时候阻塞,线程大量的时间就这样白白浪费在了等待响应上了。

收获园豆:50
Daniel Cai | 专家六级 |园豆:10424 | 2017-10-23 17:16
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册