c# await async 筆記

參考連接:http://www.cnblogs.com/xianyudotnet/p/5716908.htmlhtml

       【意義】異步方法的意義就是保證一個進程使用多線程屢次執行一個方法時,不會由於其中某一次執行阻塞調用進程
  【原理】利用方法內Task調用新線程,await使方法內等待Task結果時調用進程不被阻塞,屢次調用至關於多個線程並行。(不被阻塞的緣由應該是異步方法自己就和內部的Task跑在一個線程裏)
  【區別】普通方法只用Task也能夠並行,當方法內須要Task返回值時,等待Task結果就會阻塞調用進程。
  【應用】主要應用在沒有返回值,使用線程且須要線程返回結果的方法。多線程

  一些分析:異步

  1.異步方法有返回值會怎樣?async

  由於異步方法返回類型是Task<T>,因此獲取返回值只能await或者.Result,二者都會讓當前方法等待。線程

  2.那麼異步方法是否是沒有做用了?htm

  若是是用.Result獲取,那麼是。若是是await就不必定了。await只能在async方法中使用,因此await獲取異步方法返回值的方法也是異步的,再往上最終只能確定是一個普通方法調用異步方法。是否有用取決於普通方法內調用最上層異步方法的方式。blog

  3.爲何返回值類型是T,方法返回類型須要是Task<T>?教程

  要達到異步方法內等待線程結果不阻塞調用進程,這個方法自己就應該在線程中執行。因此無論返回類型是什麼,放到Task中運行後返回的是Task<T>。這樣被調用時至關於一個Task.Run(),也就能夠實現異步方法await了。進程

  4.爲何要實現異步方法await可等待?string

  異步方法的await其實第二點已經分析了,實現異步方法await能夠容許異步方法內繼續調用異步方法,把異步操做從底層向上層傳遞。而可以傳遞到的最上層是什麼,是static void Main(),因此最終仍是普通方法調用異步方法。也就是說不能繼續使用await等待異步方法的結果了,當最上層不關注返回結果時,無論內部有多少次await異步方法的調用,依然仍是多線程的並行。若是最上層非要關注異步方法的返回結果,用.Result獲取其結果,那我無話可說。

  5.關於Async和await。

  await其實不光是一個簡單的讓下一行代碼等待異步方法或Task結果的關鍵字。應該理解成一個擴大當前Task代碼執行範圍的命令。

  從最開始的await Task讓整個異步方法B都能在Task中運行(因此普通方法調用異步方法B時,B內await Task結果就不會阻塞調用進程)。

  到異步方法A中await異步方法B讓異步方法A和B都在同一Task內運行(因此普通方法調用異步方法A時,A內await異步方法B的結果和B內await Task的結果就不會阻塞調用進程)

  Async用於標識一個方法是異步方法,約束其返回類型爲Task<T>。也就說內部可使用await,且方法自己是放到Task中執行的,因此代碼返回類型T,方法的返回類型倒是Task<T>。

 

  最後必定要區別異步方法和普通多線程方法的用處,他們的關鍵區別就是是否須要單獨等待線程的執行結果。不要把異步方法當多線程方法用了。

 

上面這些話是摘抄連接中的做者的,網上教程找那麼多,所有沒有說道點子上,這篇文章寫得很是不錯,讓我茅塞頓開。

我一直以爲這個關鍵字沒有用,能夠本身用線程來實現,不知道有啥做用,仔細研讀上面這文章才明白過來。

本人總結:

一、異步和多線程不是一種東西,異步能夠經過多線程來實現。

二、若是隻執行不須要結果什麼的,二者沒有什麼區別,關鍵點在於返回值的處理狀況。若是異步方法中的代碼依賴結果往執行,那麼若是開多線程,調用Result方法,會致使方法阻塞,好比下面代碼中的threadTest方法,會按照調用順序執行。若是使用await關鍵字,那麼是不會阻塞這個異步方法,該調用還調用,異步執行完成後會自動執行下面的代碼,好比asyncTest。建議將下面代碼跑跑看看執行的效果就會明白。

 

        static void Main(string[] args)
        {
            Console.WriteLine("主線程開始");

            for (int i = 0; i < 10; i++)
            {
                //string aa = threadTest(i);
                Task<string> aa = asyncTest(i);
            }
            Console.WriteLine("主線程結束");
            Console.ReadKey();
        }

        //常規開線程辦法處理
        public static string threadTest(int i)
        {
            string r = Task.Run(() =>
            {
                Console.WriteLine("普通多線程方法{0}Task被執行", i);
                Thread.Sleep(100);
                return i.ToString();
            }).Result;
            Console.WriteLine("普通方法{0}執行完畢,結果{1}", i, r);
            return r;
        }

        //使用await和async來實現異步
        public static async Task<string> asyncTest(int i)
        {
            string r = await Task.Run(() =>
            {
                Console.WriteLine("異步方法{0}Task被執行", i);
                Thread.Sleep(500);
                return i.ToString();
            });
            Console.WriteLine("異步方法{0}執行完畢,結果{1}", i, r);
            return r;
        }

 

參考連接:http://www.ituring.com.cn/book/miniarticle/65777

相關文章
相關標籤/搜索