• async/await


    网上关于async/await的知识有很多,看了很多但不如自己实践一遍来得快,所以这里记录下我的理解和大家学习下。

    因为await会时被修饰的代码处于等待状态,就相当于阻塞那段代码.
    会有阻塞转移的情况发生

    首先以最简单的同步方法来开始如下

    网上关于async / await的知识有很多, 看了很多但不如自己实践一遍来得快, 所以这里记录下我的理解和大家学习下。
    首先以最简单的同步方法来开始如下
    private static void Test()
    {
        Console.WriteLine(2);
        GetV();
        Console.WriteLine(6);
    }
    private static void GetV()
    {
        Console.WriteLine(3);
        Console.WriteLine(4);
        Console.WriteLine(5);
    }
    static void Main(string[] args)
    {
        Console.WriteLine(1);
        Test();
        Console.WriteLine(7);
    }

    输出如下:这个就是按照同步的方法,一步步的去执行的

     当时当我们简单的使用Task.Run时

    private static void Test()
    {
        Console.WriteLine(2);
        GetV();
        Console.WriteLine(6);
    }
    private static void GetV()
    {
        Console.WriteLine(3);
        Task.Run(() =>
        {
            Thread.Sleep(10000);
            Console.WriteLine(4);
        });
        Console.WriteLine(5);
    }
    static void Main(string[] args)
    {
        Console.WriteLine(1);
        Test();
        Console.WriteLine(7);
    }

    因为分配了新的线程,所以4会被最晚打印出来;因为"4" ,“睡”了10s

    这时候我们使用async/await呢?

    private static async Task Test()
    {
        Console.WriteLine(2);
        await GetV();
        Console.WriteLine(6);
    }
    private static async Task GetV()
    {
        Console.WriteLine(3);
        await Task.Run(() =>
        {
            Thread.Sleep(10000);
            Console.WriteLine(4);
        });
        Console.WriteLine(5);
    }
    static void Main(string[] args)
    {
        Console.WriteLine(1);
        var v = Test();//这里注意,虽然Test是异步方法,但是在Main函数中,并没有异步来修饰它
        Console.WriteLine(7);
    }

    所以这个时候打印结果:

    因为await会时被修饰的代码处于等待状态,就相当于阻塞那段代码,
    Test方法里面执行到await时就会等待Getv的方法的执行,就会阻塞Test方法,
    但是不会阻塞Main方法,可以理解为await将阻塞的控制权交给了Test方法。
    这里有个我的理解是:Main方法启动,照常打印出来1
    然后就是执行到了Test()方法了,这个时候TEST()方法里的GETV(),方法是被await,
    GETV中是照样输出3
    然后等待10s输出4,再输出5;
    然后再输出6
    
    哦哦,就是理解一条:被await的就会等待,
    一开始是修饰的await GetV()----》await Task.Run(),这个等待转移了,
    最终将阻塞的控制权转移到Task.Run()上面了,
    所以3还是同步输出了。
    因为6在await GetV()下面,所以要等待异步执行完毕。
    1237    456

    但是当我们把Test的await去掉了,这时候Test方法就没有了阻塞的权限,而是去寻找下一个await来转移控制权,如下

    这个时候不会阻塞Test了。而是直接寻找到Task.Run(),这个方法了。因为“3”在阻塞线程前面,所以还是同步输出了。“5”在后面,所以还是要在“4”之后输出

    private static void Test()
    {
        Console.Out.WriteLine(2);
        GetV();
        Console.Out.WriteLine(6);
    }
    private static async Task GetV()
    {
        Console.Out.WriteLine(3);
        await Task.Run(() =>
        {
            Thread.Sleep(10000);
            Console.WriteLine(4);
        });
        Console.Out.WriteLine(5);
    }
    static void Main(string[] args)
    {
        Console.Out.WriteLine(1);
        Test();
        Console.Out.WriteLine(7);
        string str = Console.ReadLine();
    }
    1236745

    如果在main方法里面使用Task.GetAwaiter或者Task.Result呢,这两个东西我的理解就是阻塞线程,等待异步返回结果,但是它阻塞的是当前的方法,如下代码

    private static async Task Test()
    {
        Console.Out.WriteLine(2);
        GetV();
        Console.Out.WriteLine(6);
    }
    private static async Task GetV()
    {
        Console.Out.WriteLine(3);
        await Task.Run(() =>
        {
            Thread.Sleep(10000);
            Console.WriteLine(4);
        });
        Console.Out.WriteLine(5);
    }
    static void Main(string[] args)
    {
        Console.Out.WriteLine(1);
        Test().GetAwaiter().GetResult();
        Console.Out.WriteLine(7);
        string str = Console.ReadLine();
    }

    它只会阻塞main方法的,但是对于Test方法它是无法阻塞的,Test方法仍然会异步执行,4,5仍然以异步的方法打印出来,所以打印结果如下

     Task.Result也是如此,只会阻塞当前的方法,我觉得和await相似,只给了当前使用Task.GetAwaiter或者Task.Result的方法阻塞全,没有权利阻塞别的方法。

  • 相关阅读:
    事件溯源的使用实例
    CQRS With Axon
    maven打包带依赖
    MongoDB Query语法和工具
    docker 在外部指定参数变量 spring
    logger 过滤部分类的logger
    Nginx ServerName指令
    Nginx 处理Http请求简单流程
    Listen 指令
    Nginx 配置
  • 原文地址:https://www.cnblogs.com/ZkbFighting/p/8306073.html
Copyright © 2020-2023  润新知