async、await、Task这三个,大多数情况下,都是会同时出现的,它们控制着异步代码,简单说你可以理解成一个线程。

有await关键字,就必然会有async,当方法体内会有返回值时,也会必然有Task。

对于调用者来说,他就有两种调用方式:

1.也是调用时加上await关键字,这样在他调用的局部代码中是“同步”的;

2.调用的时候用Task类型来接收,这样就相当于创建了一个非阻塞的线程,执行你的代码,然后代码去干其他事情,等需要返回结果的时候,调用Task的Result属性,若此时异步代码已经执行完,便可以立马拿到返回结果,若还没执行完,则会同步等待返回结果,如果只是调用了异步方法,并没有做任何的await或等待Result的话,则是完全不阻塞的。

而不带async、await、Task的方法,就是普通的同步代码,需要多线程执行时,要么包装到Task中去执行,要么创建一个Thread去执行。

下面简单写个demo程序演示下同步和异步的效果:

public static int DoSomething(string str)
        {
            Console.WriteLine("同步代码开始,传入的参数是:" + str);
            Thread.Sleep(2000);//模拟一些耗时的操作,如读取文件、网络请求等
            Console.WriteLine("同步代码结束,传入的参数是:" + str);
            return 1;
        }

        public static async Task<int> DoSomethingAsync(string str)
        {
            Console.WriteLine("异步代码开始,传入的参数是:" + str);
            await Task.Delay(2000);//模拟一些耗时的操作,如读取文件、网络请求等
            Console.WriteLine("异步代码结束,传入的参数是:" + str);
            return 1;
        }

然后不同的调用方式:

var sw = Stopwatch.StartNew();
            var sum = DoSomething("sync");
            Console.WriteLine("我去做其他的事情,大约需要1s");
            Thread.Sleep(1000);
            Console.WriteLine("同步代码耗时:" + sw.ElapsedMilliseconds + "ms");
            Console.WriteLine("\r\n-----------------------分割线----------------------\r\n");
            sw.Restart();

            DoSomethingAsync("async1");
            Console.WriteLine("异步代码不等待耗时:" + sw.ElapsedMilliseconds + "ms");
            Console.WriteLine("\r\n-----------------------分割线----------------------\r\n");

            sw.Restart();
            var task = DoSomethingAsync("async2");
            Console.WriteLine("我先去做其他的事情,大约需要1s");
            Thread.Sleep(1000);
            var result = task.Result;
            Console.WriteLine("异步代码需要等待返回结果的时候耗时:" + sw.ElapsedMilliseconds + "ms");
            Console.WriteLine("\r\n-----------------------分割线----------------------\r\n");

            sw.Restart();
            await DoSomethingAsync("async3");
            Console.WriteLine("我先await再去做其他的事情,大约需要1s");
            Thread.Sleep(1000);
            Console.WriteLine("await异步代码的时候耗时:" + sw.ElapsedMilliseconds + "ms");

运行结果如下:

await axios 解析 await task_await axios 解析

可以看出:

同步代码是完全的阻塞,按代码先后顺序依次执行的;

而异步不等待的,完全就是非阻塞的;

而Task.Result的形式,则是同步和异步在同时运行,最终耗时以耗时较长的为准;

await异步代码,则和同步的效果是差不多的。