Async Await异步调用WebApi

先铺垫一些基础知识web

在 .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
相关文章
相关标签/搜索