Async Await异步调用WebApi
2016-02-16 20:29
597 查看
先铺垫一些基础知识
在 .net 4.5中出现了 Async Await关键字,配合之前版本的Task 来使得开发异步程序更为简单易控。
在使用它们之前 我们先关心下 为什么要使用它们。好比 一个人做几件事,那他得一件一件的做完,而如果添加几个人手一起帮着做
很显然任务会更快的做好。这就是并行的粗浅含义。
在程序中,常见的性能瓶颈在于 NetWork I/O 瓶颈 , CPU 瓶颈, 数据库I/O瓶颈,这些瓶颈使得我们的程序运行的很慢,我们想办法去优化。因为并行开发本身就加重CPU负担,所以一般将并行用来优化 由另外两种I/O造成的瓶颈。
比如这边的两个方法, 通过Thread.Sleep来模拟程序耗时5秒,那如果我们再写一个方法来调用
很显然 会耗时超过10s钟,如果我们用task开启两个线程 同时执行 如下
[align=left]那执行时间只会是5s多一点, 大大提升了我们程序的性能。[/align]
[align=left] [/align]
[align=left]在了解了这些基础之后,我们来接触异步程序的实际运用场景。[/align]
[align=left]我们调用 WebApi的时候,因为要经过网络传输,有时候会很慢。 这时候便有了我们用异步一展身手的时候了。[/align]
[align=left]我们的webapi如下[/align]
都是模拟耗时5秒钟,现在要同时调用这些api获得 数据并一起展示
[align=left]很显然 调用这个webapi要5秒多,那么我们要同时获取的时候,就要分别调用TaskGetProduct() TaskGetWidget() TaskGetGizmos()[/align]
[align=left]和前面的经验一样,这要是同步的话不得15秒多。。这要如何忍受。。[/align]
[align=left]很显然要异步获取[/align]
三个任务同时进行,花费5秒多。ok
附上源代码 http://files.cnblogs.com/files/JasonShenW/WebApi.rar http://files.cnblogs.com/files/JasonShenW/WebMVC.rar
在 .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" ); }
[align=left]那执行时间只会是5s多一点, 大大提升了我们程序的性能。[/align]
[align=left] [/align]
[align=left]在了解了这些基础之后,我们来接触异步程序的实际运用场景。[/align]
[align=left]我们调用 WebApi的时候,因为要经过网络传输,有时候会很慢。 这时候便有了我们用异步一展身手的时候了。[/align]
[align=left]我们的webapi如下[/align]
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); } }
[align=left]很显然 调用这个webapi要5秒多,那么我们要同时获取的时候,就要分别调用TaskGetProduct() TaskGetWidget() TaskGetGizmos()[/align]
[align=left]和前面的经验一样,这要是同步的话不得15秒多。。这要如何忍受。。[/align]
[align=left]很显然要异步获取[/align]
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
相关文章推荐
- leetcode 182. Duplicate Emails
- Unix Study之--AIX系统监控工具tops
- Unix Study之--AIX系统监控工具tops
- DataGuard强制切换(failover)
- Raising Modulo Numbers(POJ 1995 快速幂)
- 本文只为记录,自学 CAAnaimation 中正在学习中...
- Keychains中此证书签发者无效的解决方法
- 一次Hadoop脑裂的修复(Cloudera hadoop split-brain repair)
- 浅谈xaingce apk样本分析
- Rails Commands
- python的类变量和实例变量 http://blog.csdn.net/chenggong2dm/article/details/9030481
- Rails Commands
- TairResult 缓存 计数器的使用
- 正常使用谷歌搜索引擎和Gmail的方法!
- 在mac上配置git send-email使用gmail
- Contains Duplicate,Contains Duplicate II,Contains Duplicate III
- 【DP】AIM Tech Round (Div. 2) D
- QMainWindow布局和QDialog布局的区别
- 500 OOPS: vsftpd: refusing to run with writable anonymous root Login failed.
- cvpr读书笔记[3]:traincascade与AdaBoost的opencv实现框架