8、Task、async、await小记

个人理解:

1、同步/异步,这是形容词,后面还有个名词叫方法。

2、为了代码的可读性和复用性,我们经常会将能实现特定功能的一部分代码进行封装成一个方法,然后在程序运行时调用该方法。

3、于是就出现了同步异步的概念。这个同步和异步就是指多个方法运行时的流程顺序。

一、async、await 无返回值

        static void Main(string[] args)
        {
            Console.WriteLine("主线程开始");
            TestAsyncNoRecall(); 
            Console.WriteLine("主线程结束");

            Console.ReadKey();
        }
        
        public static async Task TestAsyncNoRecall()
        {
            Console.WriteLine("异步方法开始");
            await Task.Run(() =>
            {
                Thread.Sleep(1000);
                Console.WriteLine("异步线程执行");
            });
            Console.WriteLine("异步方法结束");
        }

控制台显示:

说明:首先,这里面有两个方法,分别是main和TestAsyncNoRecall,同步异步就是指这两个方法运行时的流程顺序。

程序从main方法开始,遇到TestAsyncNoRecall方法后,进入该方法。然后直到第四步之前,main和TestAsyncNoRecall都是同步执行的。谁也没让谁,从上到下,按照面向过程的规则,该谁执行就谁执行。但是asyncTestAsyncNoRecall有关键字修饰,并且方法体内部有await关键字,因此,到遇到await后,main方法就不等了,直接跳出TestAsyncNoRecall方法体,执行main方法中的下面的代码,而asyncTestAsyncNoRecall开启了一个异步线程,去处理线程内部逻辑,等线程执行完了,再接着执行asyncTestAsyncNoRecall下面的代码,所以打印结果就如同上面图所示。

总结:如果方法A中调用了一个异步方法B(没有返回值),对于方法A的流程来说,可以不用看方法B,直接略过看下面的代码。

二、async、await有返回值

        static void Main(string[] args)
        {
            Console.WriteLine("主线程开始");
             
            Task<int> tInt = TestAsync();
            Console.WriteLine(tInt.Result);
            Console.WriteLine("主线程结束");

            Console.ReadKey();
        }
    
        public static async Task<int> TestAsync()
        {
            Console.WriteLine("异步方法开始");
            int n= await Task.Run(() =>
            {
                Thread.Sleep(1000);
                Console.WriteLine("异步线程执行");
                return 3;
            });
            Console.WriteLine("异步方法结束");
            return n;
        }

控制台显示:

说明:没错,就是这样的,虽然长得和异步一样,而且完全符合异步语法,但从结果和流程来看,都和同步执行结果一样。

因为main方法中使用了异步方法TestAsync里面的结果,所以需要等待TestAsync运行完才能运行main下面的代码。

修改:调用带有返回值的TestAsync方法,但是不设置接收值

        static void Main(string[] args)
        {
            Console.WriteLine("主线程开始"); 
            TestAsync(); 
            Console.WriteLine("主线程结束");

            Console.ReadKey();
        }
    
        public static async Task<int> TestAsync()
        {
            Console.WriteLine("异步方法开始");
            int n= await Task.Run(() =>
            {
                Thread.Sleep(1000);
                Console.WriteLine("异步线程执行");
                return 3;
            });
            Console.WriteLine("异步方法结束");
            return n;
        }

控制台显示:

其实就是不使用异步方法的返回值。

总结:异步方法的语法结构基本就是这些东西,通过async和await的修饰来完成,但是如果异步方法的使用不规范,就会发现和同步方法没什么区别,而且在性能上还不如同步,因为由于async的存在,会在编译器底层做一些工作,会消耗一些资源。所以尽量把业务理顺,不要使用异步方法中的结构。

三、async 不使用await

        static void Main(string[] args)
        {
            Console.WriteLine("主线程开始");
            TestAsyncNoRecall();
            //Task<int> tInt = TestAsync();
            //Console.WriteLine(tInt.Result);
            Console.WriteLine("主线程结束");

            Console.ReadKey();
        }

        public static async Task TestAsyncNoRecall()
        {
            Console.WriteLine("异步方法开始");
            Task.Run(() =>
            {
                Thread.Sleep(1000);
                Console.WriteLine("异步线程执行");
            });
            Console.WriteLine("异步方法结束");
        }

控制台显示:

说明:TestAsyncNoRecall里面并没有await 修饰词,说明TestAsyncNoRecall是一个同步方法,所以才会执行完TestAsyncNoRecall里面的最后一句再返回main执行,至于Task最后执行那是因为新开的一个线程。

总结:async和await一定要配合使用,(await关键字只能出现在async修饰的异步方法中,出现在其他地方会报错),这样才能实现异步方法,不然就是个同步方法。

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值