您的位置:威尼斯官方网站 > 威尼斯正规官网 > 自身感到大家的await与async的展开药情势不科学

自身感到大家的await与async的展开药情势不科学

发布时间:2019-11-20 22:47编辑:威尼斯正规官网浏览(85)

    C#5.0出产了新语法,await与async,但相信大家要么少之又少使用它们。关于await与async有多数篇章批注,但有未有那般大器晚成种感到,你看完后,总以为那东西特别不错,但用的时候,总是想不起来,恐怕不知晓该怎么用。

    为啥吧?笔者以为贵裔的await与async的展开方式不正确。

     准确的展开药方式

     

    先是看下使用限制。

    1、await 只好在标志了async的函数内选拔。

    2、await 等待的函数必需标志async。

    有未有痛感那是个循环?对的,那正是个巡回。那也等于为什么大家不怎么用他们的缘由。这一个轮回很讨厌,那么怎么消亡那几个轮回呢?

    【很简短,await等待的是线程,不是函数。】

    不知道吧?不妨,接着看下来。

    下边从头来说解,首先看那样生龙活虎组相比较

    public static int NoAsyncTest()
    {
       return 1;
    }
    public static async Task<int> AsyncTest()
    { 
      return 1;
    }
    

     async Task<int>等于int

    那意味大家在日常调用那八个函数时,他们是同样的。那么用async Task<int>来修饰int指标是什么样啊?

    指标是为着让那些点子这么被调用 await AsyncTest(),但直接这样调用,并不会张开线程,那那样困苦的修饰是否就没怎么意思了吧。

    自然不是,这如哪天候会让 await AsyncTest()有意义吗?

    我们随后往下看,修正AsyncTest如下。然后,那时再调用await AsyncTest(),你会美妙的开掘,依然未有卵用。。。

    Excute方法正常实践,而AsyncTest内运转的线程,自身施行本人的。

    public static async void Excute()
     {
           Console.WriteLine(Thread.CurrentThread.GetHashCode() + " 开始 Excute " + DateTime.Now);
           await AsyncTest();
           Console.WriteLine(Thread.CurrentThread.GetHashCode() + " 结束 Excute " + DateTime.Now);
     }
    
     public static async Task<int> AsyncTest()
     {
            Task.Run(() =>
                {
                    Console.WriteLine(Thread.CurrentThread.GetHashCode() + " Run1 " + DateTime.Now);
                    Thread.Sleep(1000);
                });
                return 1;
     }
    

    图片 1

    别发急,我们稍作调节,在线程前面扩展.GetAwaiter().GetResult()。那句话是怎么用的呢?是用来获得线程再次来到值的。

    其生龙活虎逻辑是这么的,假设想要获取线程重返结果,就自然要等待线程停止。

    运转一下,大家将看下边包车型地铁结果。

    public static async Task<int> AsyncTest()
            {
                Task.Run(() =>
                {
                    Console.WriteLine(Thread.CurrentThread.GetHashCode() + " Run1 " + DateTime.Now);
                    Thread.Sleep(1000);
                }).GetAwaiter().GetResult();
                return 1;
            }
    

    图片 2 

    唯独,好像await AsyncTest();如故没启成效。没有错,事实正是,他实在不会起效果。。。

    那正是说怎么本领让她起效用吧?

    率先,大家定义叁个常备函数,他的再次回到值是一个Task,然后大家赢得Task后,运维它,再用await等待那一个Task。

    于是乎大家就收获这么的结果。

     public static async void Excute()
            {
                Console.WriteLine(Thread.CurrentThread.GetHashCode() + " 开始 Excute " + DateTime.Now);
                var waitTask = AsyncTestRun();
                waitTask.Start();
                int i = await waitTask;
                Console.WriteLine(Thread.CurrentThread.GetHashCode() + " i " + i);
                Console.WriteLine(Thread.CurrentThread.GetHashCode() + " 结束 Excute " + DateTime.Now);
            }
            public static Task<int> AsyncTestRun()
            {
                Task<int> t = new Task<int>(() => {
                    Console.WriteLine(Thread.CurrentThread.GetHashCode() + " Run1 " + DateTime.Now);
                    Thread.Sleep(1000);
                    return 100;
                });
                return t;
            }
    

    图片 3  

    如图,那样写await AsyncTest();就起效果了。

    进而,照旧那句话,await等待的是线程,不是函数。

    但在图里,大家开掘很意外的一些,甘休Excute也是线程3,而不是线程1。也正是说,Await会对线程实行优化。

    上边看下两组代码的相持统意气风发,让大家就更明白的询问下Await。

    先是组,使用await等待线程。

    public static async void Excute()
    {
       Console.WriteLine(Thread.CurrentThread.GetHashCode() + " 开始 Excute " + DateTime.Now);
       await SingleAwait(); 
       Console.WriteLine(Thread.CurrentThread.GetHashCode() + " 结束 Excute " + DateTime.Now);
    }
    
    public static async Task SingleAwait()
    {
         Console.WriteLine(Thread.CurrentThread.GetHashCode() + " AwaitTest开始 " + DateTime.Now);
         await Task.Run(() =>
                {
                    Console.WriteLine(Thread.CurrentThread.GetHashCode() + " Run1 " + DateTime.Now);
                    Thread.Sleep(1000);
                });
                await Task.Run(() =>
                {
                    Console.WriteLine(Thread.CurrentThread.GetHashCode() + " Run2 " + DateTime.Now);
                    Thread.Sleep(1000);
                });
                Console.WriteLine(Thread.CurrentThread.GetHashCode() + " AwaitTest结束 " + DateTime.Now);
                return;
    }
    

    图片 4

     

    其次组,使用等待线程结果,等待线程。

     public static async void Excute()
    {
         Console.WriteLine(Thread.CurrentThread.GetHashCode() + " 开始 Excute " + DateTime.Now);
                await SingleNoAwait(); 
         Console.WriteLine(Thread.CurrentThread.GetHashCode() + " 结束 Excute " + DateTime.Now);
            }
    public static async Task SingleNoAwait()
    {
          Console.WriteLine(Thread.CurrentThread.GetHashCode() + " SingleNoAwait开始 " + DateTime.Now);
           Task.Run(() =>
            {
                    Console.WriteLine(Thread.CurrentThread.GetHashCode() + " Run1 " + DateTime.Now);
                    Thread.Sleep(1000);
                }).GetAwaiter().GetResult();
                Task.Run(() =>
                {
                    Console.WriteLine(Thread.CurrentThread.GetHashCode() + " Run2 " + DateTime.Now);
                    Thread.Sleep(1000);
                }).GetAwaiter().GetResult();
                Console.WriteLine(Thread.CurrentThread.GetHashCode() + " SingleNoAwait结束 " + DateTime.Now);
                return;
    }
    

    图片 5

    能够分明的看来,第二组,线程重新回来了主线程第11中学,而首先组,已经被优化到了线程4中。

     

     结语

    await是黄金时代种很便捷的语法,他的确会让代码简洁一些,但他主动优化线程的法力,假若不打听就应用,大概会造成一些意想不到的BUG发生。

    那也是合法为啥只提供了await调用服务的例证,因为,在程序内调用,await依旧要打听后,再使用,才安然。

    C#语法——委托,架构的血流

    C#语法——元组类型

    C#语法——泛型的种种运用


    注:此作品为原创,招待转发,请在作品页面显然地点给出此文链接!
    若你感到那篇文章还不易,请点击下右下角的推荐,特别感激!

    本文由威尼斯官方网站发布于威尼斯正规官网,转载请注明出处:自身感到大家的await与async的展开药情势不科学

    关键词: