Async Await非同步調用WebApi

来源:http://www.cnblogs.com/JasonShenW/archive/2016/02/16/5193785.html
-Advertisement-
Play Games

先鋪墊一些基礎知識 在 .net 4.5中出現了 Async Await關鍵字,配合之前版本的Task 來使得開發非同步程式更為簡單易控。 在使用它們之前 我們先關心下 為什麼要使用它們。好比 一個人做幾件事,那他得一件一件的做完,而如果添加幾個人手一起幫著做 很顯然任務會更快的做好。這就是並行的粗淺


先鋪墊一些基礎知識

在 .net 4.5中出現了 Async Await關鍵字,配合之前版本的Task 來使得開發非同步程式更為簡單易控。   在使用它們之前 我們先關心下 為什麼要使用它們。好比 一個人做幾件事,那他得一件一件的做完,而如果添加幾個人手一起幫著做 很顯然任務會更快的做好。這就是並行的粗淺含義。   在程式中,常見的性能瓶頸在於 NetWork I/O 瓶頸 , CPU 瓶頸, 資料庫I/O瓶頸,這些瓶頸使得我們的程式運行的很慢,我們想辦法去優化。因為並行開發本身就加重CPU負擔,所以一般將並行用來優化 由另外兩種I/O造成的瓶頸。
//sync method sample
        public static void DownLoadWebPage()
        {
            //TODO  cost 5s           
            Console.WriteLine( "DownLoadWebPage on Thread:{0}", Thread.CurrentThread.ManagedThreadId);
            Thread.Sleep(5000);
            Console.WriteLine( "End downloading the page.." );
        }

        public static void LoadDatafromDB()
        {
            //TODO  cost 5s           
            Console.WriteLine( "LoadDataFromDB on Thread:{0}", Thread.CurrentThread.ManagedThreadId);
            Thread.Sleep(5000);
            Console.WriteLine( "End loading Data.." );
        }
比如這邊的兩個方法, 通過Thread.Sleep來模擬程式耗時5秒,那如果我們再寫一個方法來調用
   public static void OurSyncJob()
        {
            Console.WriteLine( "start doing things sync" );
            DownLoadWebPage();
            LoadDatafromDB();
            //do some other things
            Console.WriteLine( "do some other things" );           
        }
很顯然 會耗時超過10s鐘,如果我們用task開啟兩個線程 同時執行 如下
       public static async Task OurAsyncJobTask()
        {
            Console.WriteLine( "start doing things async" );
            var taskA= Task.Run(() => { DownLoadWebPage(); });
            var taskB= Task.Run(() => { LoadDatafromDB(); });
            await Task.WhenAll(taskA,taskB);                  
            Console.WriteLine( "do some other things" );
        }
那執行時間只會是5s多一點, 大大提升了我們程式的性能。   在瞭解了這些基礎之後,我們來接觸非同步程式的實際運用場景。 我們調用 WebApi的時候,因為要經過網路傳輸,有時候會很慢。 這時候便有了我們用非同步一展身手的時候了。 我們的webapi如下
    public class ProductController : ApiController
    {
        public productRepo repo = new productRepo();
        public IEnumerable< Product> getProducts()
        {
            Thread.Sleep(5000); 
            return repo.GetAll();
        }
    }
    public class WidgetController : ApiController
    {
        public widgetRepo repo = new widgetRepo();
        public IEnumerable< Widget> getWidgets()
        {
            Thread.Sleep(5000);
            return repo.GetAll();
        }
    }
都是模擬耗時5秒鐘,現在要同時調用這些api獲得 數據並一起展示
    public static List <Product > TaskGetProduct()
    {
       using( HttpClient client= new HttpClient())
       {
                client.BaseAddress = new Uri( "http://localhost:52593/" );
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add( new MediaTypeWithQualityHeaderValue ("application/json" ));
                string json = client.GetString("api/Product/Products" );
                return JsonConvert.DeserializeObject< List< Product>>(json);
       }
    }
很顯然 調用這個webapi要5秒多,那麼我們要同時獲取的時候,就要分別調用TaskGetProduct() TaskGetWidget() TaskGetGizmos() 和前面的經驗一樣,這要是同步的話不得15秒多。。這要如何忍受。。 很顯然要非同步獲取
public static async Task< List< Product>> TaskGetProduct()
        {
            using( HttpClient client= new HttpClient())
            {
                client.BaseAddress = new Uri( "http://localhost:52593/" );
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add( new MediaTypeWithQualityHeaderValue ("application/json" ));
                string json = await client.GetStringAsync("api/Product/Products" );
                return JsonConvert.DeserializeObject< List< Product>>(json);
            }
        }

       public static async Task< pwgVM> RunTaskGetAll()
        {
            var task1 = TaskGetItem< Product>();
            var task2 = TaskGetItem< Gizmos>();
            var task3 = TaskGetItem< Widget>();
            await Task.WhenAll(task1,task2,task3);
            pwgVM vm = new pwgVM(task1.Result,task2.Result,task3.Result);
            return vm;
        }
三個任務同時進行,花費5秒多。ok    附上源代碼  http://files.cnblogs.com/files/JasonShenW/WebApi.rar http://files.cnblogs.com/files/JasonShenW/WebMVC.rar  
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一個程式也許會被多個用戶運行,如下:那在VB.NET的WinForm環境下,怎樣獲取User Name呢?可從下麵的方法: 代碼: Public Shared Function GetProcessOwner(ByVal ProcessName As String) As String Dim po
  • 描述線程與進程的區別? 什麼是Windows服務,它的生命周期與標準的EXE程式有什麼不同 Windows上的單個進程所能訪問的最大記憶體量是多少?它與系統的最大虛擬記憶體一樣嗎?這對於系統設計有什麼影響? EXE和DLL之間的區別是什麼? 什麼是強類型,什麼是弱類型?哪種更好些?為什麼? PID是什麼
  • 出處:http://www.cnblogs.com/_popc 引言:當前能看到很多互聯網網站中有關web前端優化都採用js合併壓縮的方式輸出。樓主找了幾個地址參考 地址1、地址2 那麼下麵就開始瞭如何實現。 1.既然需要將js合併壓縮輸出那麼就先需要構造一個如上鏈接所示的那樣的鏈接地址。 @usi
  • 【問】 假設有一個類庫文件LibraryA,其中有一個ClassA,該類的AssemblyName為“LibraryA”(編譯後的文件是LibraryA.dll)。另外有一個LibraryB.dll類庫文件,其中AssemblyName和其命名空間一樣,並且其引用LibraryA.dll。它們代碼如
  • 一、前言 在關於技術上的學習,常常有這樣那樣的計劃,而最終一個都沒有真正的落實。零散的學習,終究需要系統總結,才能使自己有所沉澱。從畢業至今,我一直在忙碌,為公司付出自己的很多很多,卻只不過是一隻只會拉磨的驢: 1、只做一樣的事情(聽從領導的安排且做好,從不質疑,殊不知領導的規劃能力很弱。) 2、只
  • 1.ViewData:可存放任意類型數據,使用時需要轉換,ViewData[“Info”]="hello",適合傳遞單個數據; 2.ViewBag:是對ViewData的封裝,可讀取ViewData保存的數據,反之亦然,ViewBag.stu=objStudent; 3.TempData:可跨視圖,
  • 1.視圖引擎:把視圖解析成瀏覽器可執行的html代碼 2.aspx視圖: <%=表達式%>: <% C#代碼段 %>: 3.razor視圖: @(表達式):@ViewData["name"],如果@後跟常量,必須用括弧括起來:@(“hello”) @{C#代碼段}:@{ if(a>b) { retu
  • 對象為null時調用給對象的屬性或方法 “未將對象引用到實例”是很多像我一樣的初學者經常遇到的一個問題,常常令人煩惱不已,那麼這個問題是怎麼發生的呢?先給大家看一張圖,我們從這張圖入手來分析這個錯誤造成的原因。 可能很多人看到這樣的代碼會覺得可笑:”能寫出這樣的代碼,看來此人的智商已“超越”人類的範...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...