關於async await的測試

async await的教程:http://www.javashuo.com/article/p-fgxlmiin-z.htmlhtml

 

異步方法:web

        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("主線程結束");
        }

結果:異步

一、主線程+異步方法內await以前的代碼按順序執行async

二、await開始(開新線程)微信支付

三、跳出異步方法(不等待),繼續執行主線程後續代碼,此時Console.WriteLine("輸出結果:" + TestAsync());拿不到TestAsync()的值編碼

四、異步方法await執行結束後,異步方法await後的代碼繼續執行spa


 調用時使用await線程

        public async Task<IActionResult> Index()
        {
            Console.WriteLine("主線程開始");
            Console.WriteLine("輸出結果:" + await TestAsync());
            Console.WriteLine("主線程結束");
        }

結果:3d

所有按順序執行,能夠正確拿到返回值


 

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自己是一個語法糖,請靈活使用

相關文章
相關標籤/搜索