zoukankan      html  css  js  c++  java
  • 关于async await的测试

    async await的教程:https://www.cnblogs.com/zhaoshujie/p/11192036.html

    异步方法:

            private async Task<string> TestAsync()
            {
                Console.WriteLine("异步方法开始");
                var task = Task.Run(() =>
                {
                    Thread.Sleep(2000);
                    Console.WriteLine("在新线程中");
                    return "新线程结束";
                });
    
                var result = await task;
                Console.WriteLine("异步方法结束");
    
                return result;
            }

    调用时不使用await

            public IActionResult Index()
            {
                Console.WriteLine("主线程开始");
                Console.WriteLine("输出结果:" + TestAsync());
                Console.WriteLine("主线程结束");
            }

    结果:

    1、主线程+异步方法内await之前的代码按顺序执行

    2、await开始(开新线程)

    3、跳出异步方法(不等待),继续执行主线程后续代码,此时Console.WriteLine("输出结果:" + TestAsync());拿不到TestAsync()的值

    4、异步方法await执行结束后,异步方法await后的代码继续执行


     调用时使用await

            public async Task<IActionResult> Index()
            {
                Console.WriteLine("主线程开始");
                Console.WriteLine("输出结果:" + await TestAsync());
                Console.WriteLine("主线程结束");
            }

    结果:

    全部按顺序执行,可以正确拿到返回值


    async await在winform中的优点是,不卡主线程,并且执行顺序不混乱,但在MVC作用有限,因为web主不结束界面总是无响应的

    在MVC中,如果有一种需求,如微信支付后台的交易记录打包下载,在这种需求时,打包下载功能耗时较长,此时我们希望网页不等待打包完成,只起到“打包中,稍后查看”的提示作用,那么就可以:

            private Task BagAsync()
            {
                var task = Task.Run(() =>
                {
                    Console.WriteLine("打包开始");
                    Thread.Sleep(2000);
                    Console.WriteLine("打包结束");
                });
    
                return task;
            }
    
            public IActionResult Index()
            {
                Console.WriteLine("准备打包");
                BagAsync();
                Console.WriteLine("后台打包中,请稍后查看。");
            }

    结果:

     

    如果以后,我们又想等打包结束以后,再显示结果,我们可以在主方法中加入await等待就行,这样一个打包方法,可以根据调用者的意愿,随时等待或不等待:

            private Task BagAsync()
            {
                var task = Task.Run(() =>
                {
                    Console.WriteLine("打包开始");
                    Thread.Sleep(2000);
                    Console.WriteLine("打包结束");
                });
    
                return task;
            }
    
            public async Task<IActionResult> Index()
            {
                Console.WriteLine("准备打包");
                await BagAsync();
                Console.WriteLine("打包成功。");
            }

     结果:

    由于BagAsync()方法没有标记async,所以他本身没有await功能,所以在BagAsync方法编写时,在Task.Run之后的方法,将不会等待,一定注意执行顺序!可手动等待。

    为什么BagAsync不标记async呢?是因为标记了async,但是我们的需是不想等待时,那么vs编译器,将会有一个提醒,当然,你也可不理它,但总是觉得比较烦。

    被调用的异步方法在编写时,不一定非得要async,也可以只是一个普通的Task方法,由主调用方法来决定是否需要等待。

    如果一个方法没有使用await,直接调用了一个普通的异步方法(无async标记),那么不会有警告,也不影响执行。

    如果一个方法没有使用await,直接调用了一个标记了async的异步方法,那么这个方法本身无需标记async,编译器会有警告,但不影响执行。

    如果一个方法使用await,来调用一个标记了async的异步方法或普通异步方法,那么这个方法也需要标记成async,否则无法通过。

    如果一个异步方法本身标记了async,代码里却没有await编译器会有的提示,但不影响执行。

    如果我们的异步方法没有返回值,并在异步方法内不需要等待,则可以不写成async,否则会在调用时时常会有警告,令人不爽。

    如果我们的异步方法拥有返回值,或在异步方法内需要等待,则可以写成async,否则无法使用await,提升编码复杂度。

    async本身是一个语法糖,请灵活使用

  • 相关阅读:
    Qt之加载QSS文件
    Qt之QSS(黑色炫酷)
    Sublime Text 2 快捷键
    QTablewidget 简单例子
    QTableview 只显示横向线
    Qt删除文件夹
    Ubuntu(Debian)apt-get
    C++中char*与wchar_t*之间的转换
    Qtl和JS、HTML通信/交互
    浅谈Socket编程
  • 原文地址:https://www.cnblogs.com/yeagen/p/11746980.html
Copyright © 2011-2022 走看看